in src/main/java/org/apache/commons/jexl3/internal/introspection/Uberspect.java [311:371]
public JexlPropertyGet getPropertyGet(
final List<PropertyResolver> resolvers, final Object obj, final Object identifier
) {
final Class<?> clazz = obj.getClass();
final String property = AbstractExecutor.castString(identifier);
final Introspector is = base();
final List<PropertyResolver> r = resolvers == null ? strategy.apply(null, obj) : resolvers;
JexlPropertyGet executor = null;
for (final PropertyResolver resolver : r) {
if (resolver instanceof JexlResolver) {
switch ((JexlResolver) resolver) {
case PROPERTY:
// first try for a getFoo() type of property (also getfoo() )
executor = PropertyGetExecutor.discover(is, clazz, property);
if (executor == null) {
executor = BooleanGetExecutor.discover(is, clazz, property);
}
break;
case MAP:
// let's see if we are a map...
executor = MapGetExecutor.discover(is, clazz, identifier);
break;
case LIST:
// let's see if this is a list or array
final Integer index = AbstractExecutor.castInteger(identifier);
if (index != null) {
executor = ListGetExecutor.discover(is, clazz, index);
}
break;
case DUCK:
// if that didn't work, look for get(foo)
executor = DuckGetExecutor.discover(is, clazz, identifier);
if (executor == null && property != null && property != identifier) {
// look for get("foo") if we did not try yet (just above)
executor = DuckGetExecutor.discover(is, clazz, property);
}
break;
case FIELD:
// a field may be? (cannot be a number)
executor = FieldGetExecutor.discover(is, clazz, property);
// static class fields (enums included)
if (obj instanceof Class<?>) {
executor = FieldGetExecutor.discover(is, (Class<?>) obj, property);
}
break;
case CONTAINER:
// or an indexed property?
executor = IndexedType.discover(is, obj, property);
break;
default:
continue; // in case we add new ones in enum
}
} else {
executor = resolver.getPropertyGet(this, obj, identifier);
}
if (executor != null) {
return executor;
}
}
return null;
}