use of org.apache.commons.jexl3.introspection.JexlPropertyGet in project commons-jexl by apache.
the class ReferenceUberspect method getPropertyGet.
@Override
public JexlPropertyGet getPropertyGet(List<PropertyResolver> resolvers, Object ref, Object identifier) {
// is this is a reference of some kind?
ReferenceHandler handler = discoverHandler(ref);
if (handler == null) {
return uberspect.getPropertyGet(resolvers, ref, identifier);
}
// do we have an object referenced ?
Object obj = handler.callGet(ref);
if (ref == obj) {
return null;
}
// obj is null means proper dereference of an optional; we dont have an object,
// we can not determine jexlGet, not a pb till we call with a not-null object
// since the result is likely to be not null... TryInvoke will fail and invoke will throw.
// from that object, get the property getter if any
JexlPropertyGet jexlGet = null;
if (obj != null) {
jexlGet = uberspect.getPropertyGet(resolvers, obj, identifier);
if (jexlGet == null) {
throw new JexlException.Property(null, Objects.toString(identifier), false, null);
}
} else {
jexlGet = new OptionalNullGetter(uberspect, identifier);
}
return new ReferenceGetExecutor(handler, jexlGet);
}
use of org.apache.commons.jexl3.introspection.JexlPropertyGet 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.JexlPropertyGet 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.JexlPropertyGet 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.JexlPropertyGet in project commons-jexl by apache.
the class DiscoveryTest method testMapIntrospection.
@Test
public void testMapIntrospection() throws Exception {
final Uberspect uber = Engine.getUberspect(null, null);
final Map<String, Object> map = new HashMap<String, Object>();
map.put("value", "MAP");
map.put("eulav", "PAM");
final JexlPropertyGet get = uber.getPropertyGet(map, "value");
final JexlPropertySet set = uber.getPropertySet(map, "value", "foo");
Assert.assertTrue("map property getter", get instanceof MapGetExecutor);
Assert.assertTrue("map property setter", set instanceof MapSetExecutor);
// introspector and uberspect should return same result
Assert.assertEquals(get, uber.getPropertyGet(map, "value"));
Assert.assertEquals(set, uber.getPropertySet(map, "value", "foo"));
// different property should return different setter/getter
Assert.assertNotEquals(get, uber.getPropertyGet(map, "eulav"));
Assert.assertNotEquals(get, uber.getPropertySet(map, "eulav", "foo"));
// setter returns argument
final Object bar = set.invoke(map, "bar");
Assert.assertEquals("bar", bar);
// getter should return last value
Assert.assertEquals("bar", get.invoke(map));
// tryExecute should succeed on same property class
final Object quux = set.tryInvoke(map, "value", "quux");
Assert.assertEquals("quux", quux);
// getter should return last value
Assert.assertEquals("quux", get.invoke(map));
// tryExecute should fail on different property class
Assert.assertEquals(AbstractExecutor.TRY_FAILED, set.tryInvoke(map, 1, "nope"));
}
Aggregations