public void validate(ExprValidationContext validationContext) throws ExprValidationException {
    reader = validationContext.getVariableService().getReader(variableName);
    if (reader == null) {
      throw new ExprValidationException(
          "A variable by name '" + variableName + " has not been declared");
    }

    // determine if any types are property agnostic; If yes, resolve to variable
    boolean hasPropertyAgnosticType = false;
    EventType[] types = validationContext.getStreamTypeService().getEventTypes();
    for (int i = 0; i < validationContext.getStreamTypeService().getEventTypes().length; i++) {
      if (types[i] instanceof EventTypeSPI) {
        hasPropertyAgnosticType |= ((EventTypeSPI) types[i]).getMetadata().isPropertyAgnostic();
      }
    }

    if (!hasPropertyAgnosticType) {
      // the variable name should not overlap with a property name
      try {
        validationContext.getStreamTypeService().resolveByPropertyName(variableName, false);
        throw new ExprValidationException(
            "The variable by name '"
                + variableName
                + "' is ambigous to a property of the same name");
      } catch (DuplicatePropertyException e) {
        throw new ExprValidationException(
            "The variable by name '"
                + variableName
                + "' is ambigous to a property of the same name");
      } catch (PropertyNotFoundException e) {
        // expected
      }
    }

    variableType = reader.getType();
    isPrimitive = reader.getEventType() == null;

    if (optSubPropName != null) {
      if (reader.getEventType() == null) {
        throw new ExprValidationException(
            "Property '" + optSubPropName + "' is not valid for variable '" + variableName + "'");
      }
      eventTypeGetter = reader.getEventType().getGetter(optSubPropName);
      if (eventTypeGetter == null) {
        throw new ExprValidationException(
            "Property '" + optSubPropName + "' is not valid for variable '" + variableName + "'");
      }
      variableType = reader.getEventType().getPropertyType(optSubPropName);
    }
  }
 public Object evaluate(
     EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) {
   Object value = reader.getValue();
   if (isPrimitive) {
     return value;
   }
   if (value == null) {
     return null;
   }
   EventBean theEvent = (EventBean) value;
   if (optSubPropName == null) {
     return theEvent.getUnderlying();
   }
   return eventTypeGetter.get(theEvent);
 }
 public boolean isConstantValue() {
   return reader != null && reader.isConstant();
 }
 public Object getValue() {
   if (reader == null) {
     throw new EPException("Variable expression node has not been initialized");
   }
   return reader.getValue();
 }
 public boolean isConstantResult() {
   return reader.isConstant();
 }