All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.paoding.rose.jade.statement.jexl.internal.introspection.RoseUberspect Maven / Gradle / Ivy
package net.paoding.rose.jade.statement.jexl.internal.introspection;
import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.internal.introspection.BooleanGetExecutor;
import org.apache.commons.jexl3.internal.introspection.DuckGetExecutor;
import org.apache.commons.jexl3.internal.introspection.FieldGetExecutor;
import org.apache.commons.jexl3.internal.introspection.IndexedType;
import org.apache.commons.jexl3.internal.introspection.Introspector;
import org.apache.commons.jexl3.internal.introspection.ListGetExecutor;
import org.apache.commons.jexl3.internal.introspection.MapGetExecutor;
import org.apache.commons.jexl3.internal.introspection.PropertyGetExecutor;
import org.apache.commons.jexl3.internal.introspection.Uberspect;
import org.apache.commons.jexl3.introspection.JexlPermissions;
import org.apache.commons.jexl3.introspection.JexlPropertyGet;
import org.apache.commons.jexl3.introspection.JexlUberspect;
import org.apache.commons.lang3.reflect.FieldUtils;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;
/**
* 重写{@link Uberspect#getPropertyGet(List, Object, Object)}方法,允许getDeclaredField
* @author zhangfusheng
* @date 2024/3/22
*/
public class RoseUberspect extends Uberspect {
public RoseUberspect(JexlPermissions permissions) {
super(null, JexlUberspect.JEXL_STRATEGY, permissions);
}
@Override
public JexlPropertyGet getPropertyGet(List resolvers, Object obj, Object identifier) {
final Class> clazz = obj.getClass();
final String property = RoseUberspect.castString(identifier);
final Introspector is = base();
final List r = resolvers == null ? JexlUberspect.JEXL_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 = RoseUberspect.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? (can not 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);
}
if (Objects.isNull(executor)) {
// a field may be? (can not be a number)
executor = RoseUberspect.fieldGetExecutorDiscover(is, clazz, property);
// static class fields (enums included)
if (obj instanceof Class>) {
executor = RoseUberspect.fieldGetExecutorDiscover(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;
}
static String castString(final Object arg) {
return arg instanceof CharSequence || arg instanceof Integer ? arg.toString() : null;
}
static Integer castInteger(final Object arg) {
return arg instanceof Number ? ((Number) arg).intValue() : null;
}
static JexlPropertyGet fieldGetExecutorDiscover(Introspector is, Class> clazz, String identifier) {
if (Objects.isNull(identifier)) return null;
final Field field1 = is.getField(clazz, identifier);
final Field field = Objects.nonNull(field1) ? field1 : FieldUtils.getDeclaredField(clazz, identifier, true);
if (Objects.isNull(field)) return null;
return new JexlPropertyGet() {
@Override
public Object invoke(Object obj) throws Exception {
return field.get(obj);
}
@Override
public Object tryInvoke(Object obj, Object key) throws JexlException.TryFailed {
if (obj.getClass().equals(field.getDeclaringClass()) && key.equals(field.getName())) {
try {
return field.get(obj);
} catch (final IllegalAccessException xill) {
return Uberspect.TRY_FAILED;
}
}
return Uberspect.TRY_FAILED;
}
@Override
public boolean tryFailed(Object rval) {
return rval == Uberspect.TRY_FAILED;
}
@Override
public boolean isCacheable() {
return true;
}
};
}
}