use of org.apache.commons.jexl3.introspection.JexlUberspect in project commons-jexl by apache.
the class Operators method contains.
/**
* The 'match'/'in' operator implementation.
* <p>
* 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.
* </p>
* @param node the node
* @param op the calling operator, =~ or !~
* @param right the left operand
* @param left the right operand
* @return true if left matches right, false otherwise
*/
protected boolean contains(final JexlNode node, final String op, final Object left, final Object right) {
final JexlArithmetic arithmetic = interpreter.arithmetic;
final JexlUberspect uberspect = interpreter.uberspect;
try {
// try operator overload
final Object result = tryOverload(node, JexlOperator.CONTAINS, left, right);
if (result instanceof Boolean) {
return (Boolean) result;
}
// use arithmetic / pattern matching ?
final Boolean matched = arithmetic.contains(left, right);
if (matched != null) {
return matched;
}
// try a contains method (duck type set)
try {
final Object[] argv = { right };
JexlMethod vm = uberspect.getMethod(left, "contains", argv);
if (returnsBoolean(vm)) {
return (Boolean) vm.invoke(left, argv);
}
if (arithmetic.narrowArguments(argv)) {
vm = uberspect.getMethod(left, "contains", argv);
if (returnsBoolean(vm)) {
return (Boolean) vm.invoke(left, argv);
}
}
} catch (final Exception e) {
throw new JexlException(node, op + " error", e);
}
// defaults to equal
return arithmetic.equals(left, right);
} catch (final ArithmeticException xrt) {
throw new JexlException(node, op + " error", xrt);
}
}
use of org.apache.commons.jexl3.introspection.JexlUberspect in project commons-jexl by apache.
the class ReferenceUberspect method discoverFind.
/**
* Discovers a an optional getter.
* <p>The method to be found should be named "{find}{P,p}property and return an Optional<?>.</p>
*
* @param is the uberspector
* @param clazz the class to find the get method from
* @param property the property name to find
* @return the executor if found, null otherwise
*/
private static JexlPropertyGet discoverFind(final JexlUberspect is, final Class<?> clazz, final String property) {
if (property == null || property.isEmpty()) {
return null;
}
// this is gross and linear, but it keeps it straightforward.
JexlMethod method;
// "find".length() == 4
final int start = 4;
// start with get<Property>
final StringBuilder sb = new StringBuilder("find");
sb.append(property);
// uppercase nth char
final char c = sb.charAt(start);
sb.setCharAt(start, Character.toUpperCase(c));
method = is.getMethod(clazz, sb.toString(), EMPTY_PARAMS);
// lowercase nth char
if (method == null) {
sb.setCharAt(start, Character.toLowerCase(c));
method = is.getMethod(clazz, sb.toString(), EMPTY_PARAMS);
}
if (method != null && Optional.class.equals(method.getReturnType())) {
final JexlMethod getter = method;
final String name = sb.toString();
return new JexlPropertyGet() {
@Override
public Object invoke(Object obj) throws Exception {
return getter.invoke(obj);
}
@Override
public Object tryInvoke(Object obj, Object key) throws JexlException.TryFailed {
return !Objects.equals(property, key) ? JexlEngine.TRY_FAILED : getter.tryInvoke(name, obj);
}
@Override
public boolean tryFailed(Object rval) {
return rval == JexlEngine.TRY_FAILED;
}
@Override
public boolean isCacheable() {
return getter.isCacheable();
}
};
}
return null;
}
use of org.apache.commons.jexl3.introspection.JexlUberspect in project commons-jexl by apache.
the class StrategyTest method testRawResolvers.
@Test
public void testRawResolvers() throws Exception {
final Object map = new HashMap<String, Object>();
final JexlEngine jexl = new JexlBuilder().create();
final JexlUberspect uberspect = jexl.getUberspect();
final JexlUberspect.PropertyResolver rfieldp = JexlUberspect.JexlResolver.FIELD;
final JexlPropertyGet fget = rfieldp.getPropertyGet(uberspect, map, "key");
Assert.assertNull(fget);
final JexlPropertySet fset = rfieldp.getPropertySet(uberspect, map, "key", "value");
Assert.assertNull(fset);
final JexlUberspect.PropertyResolver rmap = JexlUberspect.JexlResolver.MAP;
final JexlPropertyGet mget = rmap.getPropertyGet(uberspect, map, "key");
Assert.assertNotNull(mget);
final JexlPropertySet mset = rmap.getPropertySet(uberspect, map, "key", "value");
Assert.assertNotNull(mset);
}
use of org.apache.commons.jexl3.introspection.JexlUberspect in project commons-jexl by apache.
the class MethodTest method testTryFailed.
@Test
public void testTryFailed() throws Exception {
// JEXL-257
final Functor func = new Functor();
final JexlContext ctxt = new MapContext();
ctxt.set("func", func);
Object result;
final JexlUberspect uber = JEXL.getUberspect();
// tryInvoke
final JexlMethod method = uber.getMethod(func, "over", "foo", 42);
Assert.assertNotNull(method);
// tryInvoke succeeds
result = method.tryInvoke("over", func, "foo", 42);
Assert.assertEquals("foo + 42", result);
// tryInvoke fails
func.setKill(true);
try {
/*result = */
method.tryInvoke("over", func, "foo", 42);
Assert.fail("should throw TryFailed");
} catch (final JexlException.TryFailed xfail) {
Assert.assertEquals(UnsupportedOperationException.class, xfail.getCause().getClass());
}
func.setKill(false);
final JexlPropertySet setter = uber.getPropertySet(func, "under", "42");
result = setter.tryInvoke(func, "under", "42");
Assert.assertFalse(setter.tryFailed(result));
Assert.assertEquals("42", result);
final JexlPropertyGet getter = uber.getPropertyGet(func, "under");
result = getter.tryInvoke(func, "under");
Assert.assertFalse(getter.tryFailed(result));
Assert.assertEquals("42", result);
func.setKill(true);
try {
/*result = */
setter.tryInvoke(func, "under", "42");
Assert.fail("should throw TryFailed");
} catch (final JexlException.TryFailed xfail) {
Assert.assertEquals(UnsupportedOperationException.class, xfail.getCause().getClass());
}
func.setKill(false);
result = setter.tryInvoke(func, "under", "-42");
Assert.assertEquals("-42", result);
func.setKill(true);
try {
/*result = */
getter.tryInvoke(func, "under");
Assert.fail("should throw TryFailed");
} catch (final JexlException.TryFailed xfail) {
Assert.assertEquals(UnsupportedOperationException.class, xfail.getCause().getClass());
}
func.setKill(false);
result = getter.tryInvoke(func, "under");
Assert.assertFalse(getter.tryFailed(result));
Assert.assertEquals("-42", result);
}
use of org.apache.commons.jexl3.introspection.JexlUberspect in project commons-jexl by apache.
the class Operators method empty.
/**
* Check for emptyness of various types: Collection, Array, Map, String, and anything that has a boolean isEmpty()
* method.
* <p>Note that the result may not be a boolean.
*
* @param node the node holding the object
* @param object the object to check the emptyness of
* @return the evaluation result
*/
protected Object empty(final JexlNode node, final Object object) {
if (object == null) {
return true;
}
Object result = tryOverload(node, JexlOperator.EMPTY, object);
if (result != JexlEngine.TRY_FAILED) {
return result;
}
final JexlArithmetic arithmetic = interpreter.arithmetic;
result = arithmetic.isEmpty(object, null);
if (result == null) {
final JexlUberspect uberspect = interpreter.uberspect;
result = false;
// check if there is an isEmpty method on the object that returns a
// boolean and if so, just use it
final JexlMethod vm = uberspect.getMethod(object, "isEmpty", Interpreter.EMPTY_PARAMS);
if (returnsBoolean(vm)) {
try {
result = vm.invoke(object, Interpreter.EMPTY_PARAMS);
} catch (final Exception xany) {
interpreter.operatorError(node, JexlOperator.EMPTY, xany);
}
}
}
return !(result instanceof Boolean) || (Boolean) result;
}
Aggregations