All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.wycst.wast.common.expression.ElVariableInvoker Maven / Gradle / Ivy

Go to download

Wast is a high-performance Java toolset library package that includes JSON, YAML, CSV, HttpClient, JDBC and EL engines

There is a newer version: 0.0.20
Show newest version
package io.github.wycst.wast.common.expression;

import io.github.wycst.wast.common.reflect.ClassStructureWrapper;
import io.github.wycst.wast.common.reflect.GetterInfo;
import io.github.wycst.wast.common.reflect.ReflectConsts;
import io.github.wycst.wast.common.utils.CollectionUtils;
import io.github.wycst.wast.common.utils.ObjectUtils;

import java.util.Map;

/**
 * 变量调用值
 *
 * 

invoke过程: *

获取变量上下文: *

如果当前为root,则将参数直接作为上下文进行invoke,否则调用parent结果作为上下文; *

结果存储到属性value中,一个表达式开始执行到结束每个点只调用一次,表达式执行完成后清除value值; * * @Author: wangy * @Date: 2022/10/28 22:30 * @Description: */ public class ElVariableInvoker implements ElInvoker { String key; ValueInvokeHolder invokeHolder = ValueInvokeHolder.Empty; // index pos int index; // Parent or Up one level ElVariableInvoker parent; // is last or not ? boolean tail; boolean hasChildren; ElVariableInvoker(String key) { this.key = key; } ElVariableInvoker(String key, ElVariableInvoker parent) { parent.getClass(); this.key = key; this.parent = parent; } @Override public String toString() { return parent.toString() + "." + key; } public ElVariableInvoker getParent() { return parent; } public String getKey() { return key; } @Override public Object invokeDirect(Object context) { Object target = parent.invokeDirect(context); return invokeValue(target); } @Override public Object invokeDirect(Map context) { Object target = parent.invokeDirect(context); return invokeValue(target); } @Override public Object invoke(Object entityContext, Object[] variableValues) { Object value = variableValues[index]; if (value != null) return value; Object target = parent.invoke(entityContext, variableValues); return variableValues[index] = invokeValue(target); } @Override public Object invoke(Map mapContext, Object[] variableValues) { Object value = variableValues[index]; if (value != null) return value; Object target = parent.invoke(mapContext, variableValues); return variableValues[index] = invokeValue(target); } @Override public Object invokeCurrent(Map globalContext, Object parentContext, Object[] variableValues) { return variableValues[index] = invokeValue(parentContext); } @Override public Object invokeCurrent(Object globalContext, Object parentContext, Object[] variableValues) { return variableValues[index] = invokeValue(parentContext); } public Object invokeCurrent(Object globalContext, Object context) { return invokeValue(context); } public Object invokeCurrent(Map globalContext, Object context) { return invokeValue(context); } // invoke current public final Object invokeValue(Object context) { Object target; try { Class contextClass = context.getClass(); ValueInvokeHolder localHoder = this.invokeHolder; if (contextClass == localHoder.targetClass) { target = localHoder.valueInvoke.getValue(context); } else { // create ValueInvoke valueInvoke; if (context instanceof Map) { valueInvoke = new MapValueInvoke(key); } else { GetterInfo getterInfo = null; try { getterInfo = ClassStructureWrapper.get(contextClass).getGetterInfo(key); if (getterInfo.isSupportedUnsafe()) { if (getterInfo.isPrimitive()) { valueInvoke = new ObjectPrimitiveFieldInvoke(getterInfo); } else { valueInvoke = new ObjectFieldInvoke(getterInfo); } } else { valueInvoke = new ObjectGetterInvoke(getterInfo); } } catch (RuntimeException runtimeException) { if (getterInfo == null) { throw new IllegalArgumentException(String.format("Unresolved field '%s' from %s", key, contextClass.toString())); } throw runtimeException; } } target = valueInvoke.getValue(context); invokeHolder = new ValueInvokeHolder(contextClass, valueInvoke); } return target; } catch (Throwable throwable) { if (context == null) { throw new IllegalArgumentException(String.format("Unresolved field '%s' for target obj is null or not exist in the context ", key)); } throw new IllegalArgumentException(String.format("Unresolved field '%s' from %s, resion: %s", key, context.getClass(), throwable.getMessage()), throwable); } } // /** // *

获取上下文的值,暂时支持pojo对象和map // *

此方法没有安全问题; // * // * @param context // * @return // */ // final Object invokeValueSafely(Object context) { // if (context == null) return null; // Object target; // if (context instanceof Map) { // target = ((Map) context).get(key); // } else { // Class contextClass = context.getClass(); // GetterInfo getterInfo = null; // try { // getterInfo = ClassStructureWrapper.get(contextClass).getGetterInfo(key); // target = getterInfo.invoke(context); // } catch (RuntimeException throwable) { // if (getterInfo == null) { // throw new IllegalArgumentException(String.format("Unresolved field '%s' %s", key, contextClass.toString())); // } // throw throwable; // } // } // return target; // } public void setIndex(int index) { this.index = index; } public int getIndex() { return this.index; } public void internKey() { this.key = key.intern(); } public boolean isTail() { return tail; } public void setTail(boolean tail) { this.tail = tail; } public boolean isChildEl() { return false; } @Override public int size() { return 1; } /** * Variable root node */ static class RootVariableInvoke extends ElVariableInvoker { public RootVariableInvoke(String key) { super(key); } @Override public Object invokeDirect(Object context) { return invokeValue(context); } @Override public Object invokeDirect(Map context) { return context.get(key); } @Override public Object invoke(Object entityContext, Object[] variableValues) { Object value = variableValues[index]; if (value != null) return value; return variableValues[index] = invokeValue(entityContext); } @Override public Object invoke(Map mapContext, Object[] variableValues) { Object value = variableValues[index]; if (value != null) return value; return variableValues[index] = mapContext.get(key); } @Override public String toString() { return key; } } /** * 子表达式变量 */ static class ChildElVariableInvoke extends ElVariableInvoker { protected Expression el; ChildElVariableInvoke(String key) { super(key); } ChildElVariableInvoke(String key, ElVariableInvoker parent) { super(key, parent); // lazy is required // this.expression = Expression.parse(key); } private void parseChildEl() { if (el == null) { synchronized (this) { if (el == null) { el = Expression.parse(key); } } } } @Override public Object invokeDirect(Object context) { parseChildEl(); Object realKey = el.evaluate(context); Object target = parent != null ? parent.invokeDirect(context) : context; if (realKey instanceof String) { return ObjectUtils.getAttrValue(target, (String) realKey); } else if (realKey instanceof Long) { // 数组key int indexValue = ((Long) realKey).intValue(); return CollectionUtils.getElement(target, indexValue); } throw new IllegalArgumentException(String.format("Unresolved child el: '%s', val: %s ", key, String.valueOf(realKey))); } @Override public Object invokeDirect(Map context) { parseChildEl(); Object realKey = el.evaluate(context); if (parent == null) { return context.get(String.valueOf(realKey)); } else { Object target = parent.invokeDirect(context); if (realKey instanceof String) { return ObjectUtils.getAttrValue(target, (String) realKey); } else if (realKey instanceof Long) { // 数组key int indexValue = ((Long) realKey).intValue(); return CollectionUtils.getElement(target, indexValue); } } throw new IllegalArgumentException(String.format("Unresolved child el: '%s', val: %s ", key, String.valueOf(realKey))); } @Override public Object invoke(Object context, Object[] variableValues) { Object value = variableValues[index]; if (value != null) return value; parseChildEl(); Object realKey = el.evaluate(context); Object parentContext = parent != null ? parent.invoke(context, variableValues) : context; if (realKey instanceof String) { return variableValues[index] = ObjectUtils.getAttrValue(parentContext, (String) realKey); } else if (realKey instanceof Long) { // 数组key int indexValue = ((Long) realKey).intValue(); return variableValues[index] = CollectionUtils.getElement(parentContext, indexValue); } throw new IllegalArgumentException(String.format("Unresolved child el: '%s', val: %s ", key, String.valueOf(realKey))); } @Override public Object invoke(Map context, Object[] variableValues) { Object value = variableValues[index]; if (value != null) return value; parseChildEl(); Object realKey = el.evaluate(context); Object parentContext = parent != null ? parent.invoke(context, variableValues) : context; if (realKey instanceof String) { return variableValues[index] = ObjectUtils.getAttrValue(parentContext, (String) realKey); } else if (realKey instanceof Long) { // 数组key int indexValue = ((Long) realKey).intValue(); return variableValues[index] = CollectionUtils.getElement(parentContext, indexValue); } throw new IllegalArgumentException(String.format("Unresolved child el: '%s', val: %s ", key, String.valueOf(realKey))); } @Override public Object invokeCurrent(Map globalContext, Object parentContext, Object[] variableValues) { parseChildEl(); Object realKey = el.evaluate(globalContext); if (realKey instanceof String) { return variableValues[index] = ObjectUtils.getAttrValue(parentContext, (String) realKey); } else if (realKey instanceof Long) { // 数组key int indexValue = ((Long) realKey).intValue(); return variableValues[index] = CollectionUtils.getElement(parentContext, indexValue); } throw new IllegalArgumentException(String.format("Unresolved child el: '%s', val: %s ", key, String.valueOf(realKey))); } @Override public Object invokeCurrent(Object globalContext, Object parentContext, Object[] variableValues) { parseChildEl(); Object realKey = el.evaluate(globalContext); if (realKey instanceof String) { return variableValues[index] = ObjectUtils.getAttrValue(parentContext, (String) realKey); } else if (realKey instanceof Long) { // 数组key int indexValue = ((Long) realKey).intValue(); return variableValues[index] = CollectionUtils.getElement(parentContext, indexValue); } throw new IllegalArgumentException(String.format("Unresolved child el: '%s', val: %s ", key, String.valueOf(realKey))); } @Override public Object invokeCurrent(Object globalContext, Object parentContext) { parseChildEl(); Object realKey = el.evaluate(globalContext); if (realKey instanceof String) { return ObjectUtils.getAttrValue(parentContext, (String) realKey); } else if (realKey instanceof Long) { // 数组key int indexValue = ((Long) realKey).intValue(); return CollectionUtils.getElement(parentContext, indexValue); } throw new IllegalArgumentException(String.format("Unresolved child el: '%s', val: %s ", key, String.valueOf(realKey))); } @Override public Object invokeCurrent(Map globalContext, Object parentContext) { parseChildEl(); Object realKey = el.evaluate(globalContext); if (realKey instanceof String) { return ObjectUtils.getAttrValue(parentContext, (String) realKey); } else if (realKey instanceof Long) { // 数组key int indexValue = ((Long) realKey).intValue(); return CollectionUtils.getElement(parentContext, indexValue); } throw new IllegalArgumentException(String.format("Unresolved child el: '%s', val: %s ", key, String.valueOf(realKey))); } public boolean isChildEl() { return true; } @Override public String toString() { return parent.toString() + "[" + key + "]"; } } interface ValueInvoke { Object getValue(T context); } static class MapValueInvoke implements ValueInvoke> { private final String key; MapValueInvoke(String key) { this.key = key; } @Override public Object getValue(Map context) { return context.get(key); } @Override public String toString() { return "[" + key + "]"; } } final static class ObjectGetterInvoke implements ValueInvoke { private final GetterInfo getterInfo; ObjectGetterInvoke(GetterInfo getterInfo) { getterInfo.getClass(); this.getterInfo = getterInfo; } @Override public Object getValue(Object context) { return SECURE_TRUSTED_ACCESS.get(getterInfo, context); // getterInfo.invoke(context); } } final static class ObjectFieldInvoke implements ValueInvoke { private final GetterInfo getterInfo; private final long fieldOffset; ObjectFieldInvoke(GetterInfo getterInfo) { getterInfo.getClass(); this.getterInfo = getterInfo; this.fieldOffset = getterInfo.getFieldOffset(); } @Override public Object getValue(Object context) { return SECURE_TRUSTED_ACCESS.getObjectValue(context, fieldOffset); } } final static class ObjectPrimitiveFieldInvoke implements ValueInvoke { private final ReflectConsts.PrimitiveType primitiveType; private final long fieldOffset; ObjectPrimitiveFieldInvoke(GetterInfo getterInfo) { getterInfo.getClass(); this.primitiveType = getterInfo.getPrimitiveType(); this.fieldOffset = getterInfo.getFieldOffset(); } @Override public Object getValue(Object context) { return SECURE_TRUSTED_ACCESS.getPrimitiveValue(primitiveType, context, fieldOffset); } } static class ValueInvokeHolder { static final ValueInvokeHolder Empty = new ValueInvokeHolder(null, null); final Class targetClass; final ValueInvoke valueInvoke; public ValueInvokeHolder(Class targetClass, ValueInvoke valueInvoke) { this.targetClass = targetClass; this.valueInvoke = valueInvoke; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy