NullSafe.java
package org.mvel2.optimizers.impl.refl.nodes;
import org.mvel2.ParserContext;
import org.mvel2.compiler.Accessor;
import org.mvel2.compiler.AccessorNode;
import org.mvel2.integration.VariableResolverFactory;
import org.mvel2.optimizers.OptimizerFactory;
public class NullSafe implements AccessorNode {
  private AccessorNode nextNode;
  private char[] expr;
  private int start;
  private int offset;
  private ParserContext pCtx;
  private boolean topLevel;
  public NullSafe(char[] expr, int start, int offset, ParserContext pCtx, boolean topLevel) {
    this.expr = expr;
    this.start = start;
    this.offset = offset;
    this.pCtx = pCtx;
    this.topLevel = topLevel;
  }
  public Object getValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory) {
    if (ctx == null) return null;
    if (nextNode == null) {
      // If NullSafe is not a top level element, optimizer doesn't use variableFactory to resolve a bean property.
      final Accessor a = OptimizerFactory.getAccessorCompiler(OptimizerFactory.SAFE_REFLECTIVE)
              .optimizeAccessor(pCtx, expr, start, offset, ctx, elCtx, variableFactory, true, ctx.getClass(), topLevel);
      nextNode = new AccessorNode() {
        public AccessorNode getNextNode() {
          return null;
        }
        public AccessorNode setNextNode(AccessorNode accessorNode) {
          return null;
        }
        public Object getValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory) {
          return a.getValue(ctx, elCtx, variableFactory);
        }
        public Object setValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory, Object value) {
          return a.setValue(ctx, elCtx, variableFactory, value);
        }
        public Class getKnownEgressType() {
          return a.getKnownEgressType();
        }
      };
    }
    //   else {
    return nextNode.getValue(ctx, elCtx, variableFactory);
    //    }
  }
  public Object setValue(Object ctx, Object elCtx, VariableResolverFactory variableFactory, Object value) {
    if (ctx == null) return null;
    return nextNode.setValue(ctx, elCtx, variableFactory, value);
  }
  public AccessorNode getNextNode() {
    return nextNode;
  }
  public AccessorNode setNextNode(AccessorNode accessorNode) {
    return this.nextNode = accessorNode;
  }
  public Class getKnownEgressType() {
    return Object.class;
  }
}