org.apache.commons.jexl3.JexlException Java Examples

The following examples show how to use org.apache.commons.jexl3.JexlException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DuckSetExecutor.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
public Object tryInvoke(Object obj, Object key, Object value) {
    if (obj != null
        && objectClass.equals(obj.getClass())
        && method !=  null
        && ((property != null && property.equals(key))
            || (property == null && key == null))
        && valueClass.equals(classOf(value))) {
        try {
            Object[] args = {property, value};
            method.invoke(obj, args);
            return value;
        } catch (IllegalAccessException | IllegalArgumentException xill) {
            return TRY_FAILED;// fail
        } catch (InvocationTargetException xinvoke) {
            throw JexlException.tryFailed(xinvoke); // throw
        } 
    }
    return TRY_FAILED;
}
 
Example #2
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
protected Object visit(ASTDoWhileStatement node, Object data) {
    Object result = null;
    int nc = node.jjtGetNumChildren();
    /* last objectNode is the condition */
    Node condition = node.jjtGetChild(nc - 1);
    do {
        cancelCheck(node);
        if (nc > 1) {
            try {
                // execute statement
                result = node.jjtGetChild(0).jjtAccept(this, data);
            } catch (JexlException.Break stmtBreak) {
                break;
            } catch (JexlException.Continue stmtContinue) {
                //continue;
            }
        }
    } while (arithmetic.toBoolean(condition.jjtAccept(this, data)));
    return result;
}
 
Example #3
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
protected Object visit(ASTTernaryNode node, Object data) {
    Object condition;
    try {
        condition = node.jjtGetChild(0).jjtAccept(this, data);
    } catch(JexlException xany) {
        if (!(xany.getCause() instanceof JexlArithmetic.NullOperand)) {
            throw xany;
        }
        condition = null;
    }
    // ternary as in "x ? y : z"
    if (node.jjtGetNumChildren() == 3) {
        if (condition != null && arithmetic.toBoolean(condition)) {
            return node.jjtGetChild(1).jjtAccept(this, data);
        } else {
            return node.jjtGetChild(2).jjtAccept(this, data);
        }
    }
    // elvis as in "x ?: z"
    if (condition != null && arithmetic.toBoolean(condition)) {
        return condition;
    } else {
        return node.jjtGetChild(1).jjtAccept(this, data);
    }
}
 
Example #4
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
protected Object visit(ASTUnaryPlusNode node, Object data) {
    // use cached value if literal
    Object value = node.jjtGetValue();
    if (value != null && !(value instanceof JexlMethod)) {
        return value;
    }
    JexlNode valNode = node.jjtGetChild(0);
    Object val = valNode.jjtAccept(this, data);
    try {
        Object result = operators.tryOverload(node, JexlOperator.POSITIVIZE, val);
        if (result != JexlEngine.TRY_FAILED) {
            return result;
        }
        Object number = arithmetic.positivize(val);
        if (valNode instanceof ASTNumberLiteral
            && number instanceof Number
            && arithmetic.isPositivizeStable()) {
            node.jjtSetValue(number);
        }
        return number;
    } catch (ArithmeticException xrt) {
        throw new JexlException(valNode, "- error", xrt);
    }
}
 
Example #5
Source File: Engine.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
public void setProperty(JexlContext context, Object bean, String expr, Object value) {
    if (context == null) {
        context = EMPTY_CONTEXT;
    }
    // synthetize expr using register
    String src = trimSource(expr);
    src = "#0" + (src.charAt(0) == '[' ? "" : ".") + src + "=" + "#1";
    try {
        final Scope scope = new Scope(null, "#0", "#1");
        final ASTJexlScript script = parse(null, PROPERTY_FEATURES, src, scope);
        final JexlNode node = script.jjtGetChild(0);
        final Frame frame = script.createFrame(bean, value);
        final Interpreter interpreter = createInterpreter(context, frame, options);
        interpreter.visitLexicalNode(node, null);
    } catch (JexlException xjexl) {
        if (silent) {
            logger.warn(xjexl.getMessage(), xjexl.getCause());
            return;
        }
        throw xjexl.clean();
    }
}
 
Example #6
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
protected Object visit(ASTWhileStatement node, Object data) {
    Object result = null;
    /* first objectNode is the condition */
    Node condition = node.jjtGetChild(0);
    while (arithmetic.toBoolean(condition.jjtAccept(this, data))) {
        cancelCheck(node);
        if (node.jjtGetNumChildren() > 1) {
            try {
                // execute statement
                result = node.jjtGetChild(1).jjtAccept(this, data);
            } catch (JexlException.Break stmtBreak) {
                break;
            } catch (JexlException.Continue stmtContinue) {
                //continue;
            }
        }
    }
    return result;
}
 
Example #7
Source File: TemplateScript.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
public TemplateScript prepare(JexlContext context) {
    final Engine jexl = jxlt.getEngine();
    JexlOptions options = jexl.options(script, context);
    Frame frame = script.createFrame((Object[]) null);
    TemplateInterpreter.Arguments targs = new TemplateInterpreter
            .Arguments(jxlt.getEngine())
            .context(context)
            .options(options)
            .frame(frame);
    Interpreter interpreter = new TemplateInterpreter(targs);
    TemplateExpression[] immediates = new TemplateExpression[exprs.length];
    for (int e = 0; e < exprs.length; ++e) {
        try {
            immediates[e] = exprs[e].prepare(interpreter);
        } catch (JexlException xjexl) {
            JexlException xuel = TemplateEngine.createException(xjexl.getInfo(), "prepare", exprs[e], xjexl);
            if (jexl.isSilent()) {
                jexl.logger.warn(xuel.getMessage(), xuel.getCause());
                return null;
            }
            throw xuel;
        }
    }
    return new TemplateScript(jxlt, prefix, source, script, immediates);
}
 
Example #8
Source File: JexlSelectorTest.java    From nexus-public with Eclipse Public License 1.0 6 votes vote down vote up
@Test
public void testPrettyExceptionMsgNoDetail() {
  // Setup
  String expected = "at line 2 column 4";

  JexlInfo info = new JexlInfo("", 2, 4);
  // Mocked because JexlException modifies msg internally after construction
  JexlException ex = mock(JexlException.class);
  doReturn(info).when(ex).getInfo();
  doReturn("").when(ex).getMessage();

  // Execute
  String returned = JexlEngine.expandExceptionDetail(ex);

  // Verify
  assertNotNull("Returned string was not set.", returned);
  assertEquals(expected, returned);
}
 
Example #9
Source File: JexlParser.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
/**
 * Declares a local variable.
 * <p> This method creates an new entry in the symbol map. </p>
 * @param var the identifier used to declare
 * @param token      the variable name toekn
 */
protected void declareVariable(ASTVar var, Token token) {
    String name = token.image;
    if (!allowVariable(name)) {
        throwFeatureException(JexlFeatures.LOCAL_VAR, token);
    }
    if (frame == null) {
        frame = new Scope(null, (String[]) null);
    }
    int symbol = frame.declareVariable(name);
    var.setSymbol(symbol, name);
    if (frame.isCapturedSymbol(symbol)) {
        var.setCaptured(true);
    }
    // lexical feature error
    if (!declareSymbol(symbol)) {
        if (getFeatures().isLexical()) {
            throw new JexlException(var, name + ": variable is already declared");
        } else {
            var.setRedefined(true);
        }
    }
}
 
Example #10
Source File: SandboxTest.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Test
public void testMethodBlock() throws Exception {
    String expr = "foo.Quux()";
    JexlScript script = JEXL.createScript(expr, "foo");
    Foo foo = new Foo("42");
    Object result;
    result = script.execute(null, foo);
    Assert.assertEquals(foo.Quux(), result);

    JexlSandbox sandbox = new JexlSandbox();
    sandbox.block(Foo.class.getName()).execute("Quux");
    JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).safe(false).create();

    script = sjexl.createScript(expr, "foo");
    try {
        result = script.execute(null, foo);
        Assert.fail("Quux should not be accessible");
    } catch (JexlException.Method xmethod) {
        // ok, Quux should not have been accessible
        LOGGER.info(xmethod.toString());
    }
}
 
Example #11
Source File: JexlParser.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
/**
 * Called by parser at end of node construction.
 * <p>
 * Detects "Ambiguous statement" and 'non-left value assignment'.</p>
 * @param node the node
 * @throws ParseException
 */
protected void jjtreeCloseNodeScope(JexlNode node) throws ParseException {
    if (node instanceof ASTAmbiguous) {
        throwAmbiguousException(node);
    }
    if (node instanceof ASTJexlScript) {
        if (node instanceof ASTJexlLambda && !getFeatures().supportsLambda()) {
            throwFeatureException(JexlFeatures.LAMBDA, node.jexlInfo());
        }
        ASTJexlScript script = (ASTJexlScript) node;
        // reaccess in case local variables have been declared
        if (script.getScope() != frame) {
            script.setScope(frame);
        }
        popFrame();
    } else if (ASSIGN_NODES.contains(node.getClass())) {
        JexlNode lv = node.jjtGetChild(0);
        if (!lv.isLeftValue()) {
            throwParsingException(JexlException.Assignment.class, null);
        }
    }
    // heavy check
    featureController.controlNode(node);
}
 
Example #12
Source File: SandboxTest.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Test
public void testMethodNoJexl() throws Exception {
    Foo foo = new Foo("42");
    String[] exprs = {
        "foo.cantCallMe()",
        "foo.tryMe()",
        "foo.tryMeARiver()",
        "foo.callMeNot()",
        "foo.NONO",
        "new('org.apache.commons.jexl3.SandboxTest$Foo', 'one', 'two')"
    };
    JexlScript script;
    Object result;

    JexlEngine sjexl = new JexlBuilder().strict(true).safe(false).create();
    for (String expr : exprs) {
        script = sjexl.createScript(expr, "foo");
        try {
            result = script.execute(null, foo);
            Assert.fail("should have not been possible");
        } catch (JexlException.Method | JexlException.Property xjm) {
            // ok
            LOGGER.info(xjm.toString());
        }
    }
}
 
Example #13
Source File: PropertySetExecutor.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
public Object tryInvoke(Object o, Object identifier, Object value) {
    if (o != null && method != null
        // ensure method name matches the property name
        && property.equals(castString(identifier))
        // object class should be same as executor's method declaring class
        && objectClass.equals(o.getClass())
        // argument class should be eq
        && valueClass.equals(classOf(value))) {
        try {
            return invoke(o, value);
        } catch (IllegalAccessException | IllegalArgumentException xill) {
            return TRY_FAILED;// fail
        } catch (InvocationTargetException xinvoke) {
            throw JexlException.tryFailed(xinvoke); // throw
        } 
    }
    return TRY_FAILED;
}
 
Example #14
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
protected Object visit(ASTIfStatement node, Object data) {
    int n = 0;
    final int numChildren = node.jjtGetNumChildren();
    try {
        Object result = null;
        // pairs of { conditions , 'then' statement }
        for(int ifElse = 0; ifElse < (numChildren - 1); ifElse += 2) {
            Object condition = node.jjtGetChild(ifElse).jjtAccept(this, null);
            if (arithmetic.toBoolean(condition)) {
                // first objectNode is true statement
                return node.jjtGetChild(ifElse + 1).jjtAccept(this, null);
            }
        }
        // if odd...
        if ((numChildren & 1) == 1) {
            // if there is an else, there are an odd number of children in the statement and it is the last child,
            // execute it.
            result = node.jjtGetChild(numChildren - 1).jjtAccept(this, null);
        }
        return result;
    } catch (ArithmeticException xrt) {
        throw new JexlException(node.jjtGetChild(n), "if error", xrt);
    }
}
 
Example #15
Source File: JexlEngine.java    From nexus-public with Eclipse Public License 1.0 6 votes vote down vote up
/**
 * Returns detail about the given JEXL exception, expanded to make it more readable.
 */
public static String expandExceptionDetail(final JexlException e) {
  StringBuilder detailBuilder = new StringBuilder(e.getMessage());

  JexlInfo info = e.getInfo();
  if (info != null) {
    // remove condensed header, replaced below with something more readable
    Matcher matcher = JEXL_CONDENSED_INFO_HEADER.matcher(detailBuilder);
    if (matcher.find()) {
      detailBuilder.delete(matcher.start(), matcher.end());
    }

    // add more detail if we have it and it's not already part of the message
    Optional<String> detail = ofNullable(info.getDetail()).map(Object::toString);
    if (detail.isPresent() && detailBuilder.indexOf(detail.get()) < 0) {
      addContext(detailBuilder, format("in '%s'", detail.get()));
    }

    // finally add the location in a more readable form
    addContext(detailBuilder, format("at line %d column %d", info.getLine(), info.getColumn()));
  }

  return detailBuilder.toString();
}
 
Example #16
Source File: SandboxTest.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Test
public void testCantSeeMe() throws Exception {
    JexlContext jc = new MapContext();
    String expr = "foo.doIt()";
    JexlScript script;
    Object result = null;

    JexlSandbox sandbox = new JexlSandbox(false);
    sandbox.allow(Foo.class.getName());
    JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).safe(false).create();

    jc.set("foo", new CantSeeMe());
    script = sjexl.createScript(expr);
    try {
        result = script.execute(jc);
        Assert.fail("should have failed, doIt()");
    } catch (JexlException xany) {
        //
    }
    jc.set("foo", new Foo("42"));
        result = script.execute(jc);
    Assert.assertEquals(42, ((Integer) result).intValue());
}
 
Example #17
Source File: DatastoreSqlTransformer.java    From nexus-public with Eclipse Public License 1.0 6 votes vote down vote up
/**
 * Transform `a =^ "something"` into `a like "something%"`
 */
@Override
protected Object visit(final ASTSWNode node, final Object data) {
  JexlNode leftChild = node.jjtGetChild(LEFT);
  JexlNode rightChild = node.jjtGetChild(RIGHT);
  if (rightChild instanceof ASTStringLiteral) {
    transformStartsWithOperator(leftChild, (ASTStringLiteral) rightChild, (SelectorSqlBuilder) data);
  }
  else if (leftChild instanceof ASTStringLiteral) {
    transformStartsWithOperator(rightChild, (ASTStringLiteral) leftChild, (SelectorSqlBuilder) data);
  }
  else {
    throw new JexlException(node, "Expected string literal");
  }
  return data;
}
 
Example #18
Source File: DatastoreSqlTransformer.java    From nexus-public with Eclipse Public License 1.0 6 votes vote down vote up
/**
 * Transform `a != b` into `(a is null or a <> b)`
 */
@Override
protected Object visit(final ASTNENode node, final Object data) {
  JexlNode leftChild = node.jjtGetChild(LEFT);
  JexlNode rightChild = node.jjtGetChild(RIGHT);
  if (rightChild instanceof ASTStringLiteral) {
    transformNotEqualsOperator(leftChild, (ASTStringLiteral) rightChild, (SelectorSqlBuilder) data);
  }
  else if (leftChild instanceof ASTStringLiteral) {
    transformNotEqualsOperator(rightChild, (ASTStringLiteral) leftChild, (SelectorSqlBuilder) data);
  }
  else {
    throw new JexlException(node, "Expected string literal");
  }
  return data;
}
 
Example #19
Source File: TemplateEngine.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
public JxltEngine.Expression createExpression(JexlInfo info, String expression) {
    if (info == null) {
        info = jexl.createInfo();
    }
    Exception xuel = null;
    TemplateExpression stmt = null;
    try {
        stmt = cache.get(expression);
        if (stmt == null) {
            stmt = parseExpression(info, expression, null);
            cache.put(expression, stmt);
        }
    } catch (JexlException xjexl) {
        xuel = new Exception(xjexl.getInfo(), "failed to parse '" + expression + "'", xjexl);
    }
    if (xuel != null) {
        if (jexl.isSilent()) {
            jexl.logger.warn(xuel.getMessage(), xuel.getCause());
            stmt = null;
        } else {
            throw xuel;
        }
    }
    return stmt;
}
 
Example #20
Source File: TemplateEngine.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
/**
 * Evaluates this expression.
 * @param frame the frame storing parameters and local variables
 * @param context the context storing global variables
 * @return the expression value
 * @throws JexlException
 */
protected final Object evaluate(Frame frame, JexlContext context) {
    try {
        JexlOptions options = options(context);
        TemplateInterpreter.Arguments args = new TemplateInterpreter
                .Arguments(jexl)
                .context(context)
                .options(options)
                .frame(frame);
        Interpreter interpreter = new TemplateInterpreter(args);
        return evaluate(interpreter);
    } catch (JexlException xjexl) {
        JexlException xuel = createException(xjexl.getInfo(), "evaluate", this, xjexl);
        if (jexl.isSilent()) {
            jexl.logger.warn(xuel.getMessage(), xuel.getCause());
            return null;
        }
        throw xuel;
    }
}
 
Example #21
Source File: DuckGetExecutor.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
public Object tryInvoke(Object obj, Object key) {
    if (obj != null
            && objectClass.equals(obj.getClass())
            // ensure method name matches the property name
            && method != null
            && ((property == null && key == null)
            || (property != null && property.equals(key)))) {
        try {
            Object[] args = {property};
            return method.invoke(obj, args);
        } catch (IllegalAccessException | IllegalArgumentException xill) {
            return TRY_FAILED;// fail
        } catch (InvocationTargetException xinvoke) {
            throw JexlException.tryFailed(xinvoke); // throw
        }  
    }
    return TRY_FAILED;
}
 
Example #22
Source File: MethodExecutor.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Override
public Object tryInvoke(String name, Object obj, Object... args) {
    MethodKey tkey = new MethodKey(name, args);
    // let's assume that invocation will fly if the declaring class is the
    // same and arguments have the same type
    if (objectClass.equals(obj.getClass()) && tkey.equals(key)) {
        try {
            return invoke(obj, args);
        } catch (IllegalAccessException | IllegalArgumentException xill) {
            return TRY_FAILED;// fail
        } catch (InvocationTargetException xinvoke) {
            throw JexlException.tryFailed(xinvoke); // throw
        }
    }
    return JexlEngine.TRY_FAILED;
}
 
Example #23
Source File: SandboxTest.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Test
public void testGetBlock() throws Exception {
    String expr = "foo.alias";
    JexlScript script = JEXL.createScript(expr, "foo");
    Foo foo = new Foo("42");
    Object result;
    result = script.execute(null, foo);
    Assert.assertEquals(foo.alias, result);

    JexlSandbox sandbox = new JexlSandbox();
    sandbox.block(Foo.class.getName()).read("alias");
    JexlEngine sjexl = new JexlBuilder().sandbox(sandbox).strict(true).safe(false).create();

    script = sjexl.createScript(expr, "foo");
    try {
        result = script.execute(null, foo);
        Assert.fail("alias should not be accessible");
    } catch (JexlException.Property xvar) {
        // ok, alias should not have been accessible
        LOGGER.info(xvar.toString());
    }
}
 
Example #24
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
@Override
protected Object visit(ASTNENode node, Object data) {
    Object left = node.jjtGetChild(0).jjtAccept(this, data);
    Object right = node.jjtGetChild(1).jjtAccept(this, data);
    try {
        Object result = operators.tryOverload(node, JexlOperator.EQ, left, right);
        return result != JexlEngine.TRY_FAILED
               ? arithmetic.toBoolean(result) ? Boolean.FALSE : Boolean.TRUE
               : arithmetic.equals(left, right) ? Boolean.FALSE : Boolean.TRUE;
    } catch (ArithmeticException xrt) {
        JexlNode xnode = findNullOperand(xrt, node, left, right);
        throw new JexlException(xnode, "!= error", xrt);
    }
}
 
Example #25
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
@Override
protected Object visit(ASTBitwiseComplNode node, Object data) {
    Object arg = node.jjtGetChild(0).jjtAccept(this, data);
    try {
        Object result = operators.tryOverload(node, JexlOperator.COMPLEMENT, arg);
        return result != JexlEngine.TRY_FAILED ? result : arithmetic.complement(arg);
    } catch (ArithmeticException xrt) {
        throw new JexlException(node, "~ error", xrt);
    }
}
 
Example #26
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
@Override
protected Object visit(ASTLENode node, Object data) {
    Object left = node.jjtGetChild(0).jjtAccept(this, data);
    Object right = node.jjtGetChild(1).jjtAccept(this, data);
    try {
        Object result = operators.tryOverload(node, JexlOperator.LTE, left, right);
        return result != JexlEngine.TRY_FAILED
               ? result
               : arithmetic.lessThanOrEqual(left, right) ? Boolean.TRUE : Boolean.FALSE;
    } catch (ArithmeticException xrt) {
        throw new JexlException(node, "<= error", xrt);
    }
}
 
Example #27
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
@Override
protected Object visit(ASTBitwiseAndNode node, Object data) {
    Object left = node.jjtGetChild(0).jjtAccept(this, data);
    Object right = node.jjtGetChild(1).jjtAccept(this, data);
    try {
        Object result = operators.tryOverload(node, JexlOperator.AND, left, right);
        return result != JexlEngine.TRY_FAILED ? result : arithmetic.and(left, right);
    } catch (ArithmeticException xrt) {
        throw new JexlException(node, "& error", xrt);
    }
}
 
Example #28
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
@Override
protected Object visit(ASTGENode node, Object data) {
    Object left = node.jjtGetChild(0).jjtAccept(this, data);
    Object right = node.jjtGetChild(1).jjtAccept(this, data);
    try {
        Object result = operators.tryOverload(node, JexlOperator.GTE, left, right);
        return result != JexlEngine.TRY_FAILED
               ? result
               : arithmetic.greaterThanOrEqual(left, right) ? Boolean.TRUE : Boolean.FALSE;
    } catch (ArithmeticException xrt) {
        throw new JexlException(node, ">= error", xrt);
    }
}
 
Example #29
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
@Override
protected Object visit(ASTGTNode node, Object data) {
    Object left = node.jjtGetChild(0).jjtAccept(this, data);
    Object right = node.jjtGetChild(1).jjtAccept(this, data);
    try {
        Object result = operators.tryOverload(node, JexlOperator.GT, left, right);
        return result != JexlEngine.TRY_FAILED
               ? result
               : arithmetic.greaterThan(left, right) ? Boolean.TRUE : Boolean.FALSE;
    } catch (ArithmeticException xrt) {
        throw new JexlException(node, "> error", xrt);
    }
}
 
Example #30
Source File: Interpreter.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
@Override
protected Object visit(ASTUnaryMinusNode node, Object data) {
    // use cached value if literal
    Object value = node.jjtGetValue();
    if (value != null && !(value instanceof JexlMethod)) {
        return value;
    }
    JexlNode valNode = node.jjtGetChild(0);
    Object val = valNode.jjtAccept(this, data);
    try {
        Object result = operators.tryOverload(node, JexlOperator.NEGATE, val);
        if (result != JexlEngine.TRY_FAILED) {
            return result;
        }
        Object number = arithmetic.negate(val);
        // attempt to recoerce to literal class
        if ((number instanceof Number)) {
            // cache if number literal and negate is idempotent
            if (valNode instanceof ASTNumberLiteral) {
                number = arithmetic.narrowNumber((Number) number, ((ASTNumberLiteral) valNode).getLiteralClass());
                if (arithmetic.isNegateStable()) {
                    node.jjtSetValue(number);
                }
            }
        }
        return number;
    } catch (ArithmeticException xrt) {
        throw new JexlException(valNode, "- error", xrt);
    }
}