package org.mvel2.optimizers.impl.refl.nodes; import org.mvel2.MVEL; import org.mvel2.ParserContext; import org.mvel2.ast.WithNode; import org.mvel2.compiler.AccessorNode; import org.mvel2.compiler.ExecutableStatement; import org.mvel2.integration.VariableResolverFactory; import java.io.Serializable; import static org.mvel2.MVEL.executeSetExpression; import static org.mvel2.util.PropertyTools.getReturnType; public class WithAccessor implements AccessorNode { private AccessorNode nextNode; protected String nestParm; protected ExecutableStatement nestedStatement; protected WithNode.ParmValuePair[] withExpressions; public WithAccessor(ParserContext pCtx, String property, char[] expr, int start, int offset, Class ingressType) { pCtx.setBlockSymbols(true); withExpressions = WithNode.compileWithExpressions(expr, start, offset, property, ingressType, pCtx); pCtx.setBlockSymbols(false); } public AccessorNode getNextNode() { return this.nextNode; } public AccessorNode setNextNode(AccessorNode accessorNode) { return this.nextNode = accessorNode; } public Object getValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory) { if (this.nextNode == null) { return processWith(ctx, elCtx, variableFactory); } else { return this.nextNode.getValue(processWith(ctx, elCtx, variableFactory), elCtx, variableFactory); } } public Object setValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory, Object value) { return this.nextNode.setValue(processWith(ctx, elCtx, variableFactory), elCtx, variableFactory, value); } public Object processWith(Object ctx, Object thisValue, VariableResolverFactory factory) { for (WithNode.ParmValuePair pvp : withExpressions) { if (pvp.getSetExpression() != null) { executeSetExpression(pvp.getSetExpression(), ctx, factory, pvp.getStatement().getValue(ctx, thisValue, factory)); } else { pvp.getStatement().getValue(ctx, thisValue, factory); } } return ctx; } public static final class ExecutablePairs implements Serializable { private Serializable setExpression; private ExecutableStatement statement; public ExecutablePairs() { } public ExecutablePairs(String parameter, ExecutableStatement statement, Class ingressType, ParserContext pCtx) { if (parameter != null && parameter.length() != 0) { this.setExpression = MVEL.compileSetExpression(parameter, ingressType != null ? getReturnType(ingressType, parameter, pCtx) : Object.class, pCtx); } this.statement = statement; } public Serializable getSetExpression() { return setExpression; } public void setSetExpression(Serializable setExpression) { this.setExpression = setExpression; } public ExecutableStatement getStatement() { return statement; } public void setStatement(ExecutableStatement statement) { this.statement = statement; } } public Class getKnownEgressType() { return Object.class; } }