public override ExprNode Validate(ExprValidationContext validationContext) { if (ChildNodes.Length == 0 || ChildNodes.Length > 2) { throw new ExprValidationException("Cast function node must have one or two child expressions"); } var valueEvaluator = ChildNodes[0].ExprEvaluator; _sourceType = valueEvaluator.ReturnType; var typeIdentifier = _typeIdentifier.Trim(); // determine date format parameter var namedParams = ExprNodeUtility.GetNamedExpressionsHandleDups(ChildNodes); ExprNodeUtility.ValidateNamed(namedParams, new String[] { "dateformat" }); ExprNamedParameterNode dateFormatParameter = namedParams.Get("dateformat"); if (dateFormatParameter != null) { ExprNodeUtility.ValidateNamedExpectType(dateFormatParameter, typeof(string)); } // identify target type // try the primitive names including "string" _targetType = TypeHelper.GetPrimitiveTypeForName(typeIdentifier).GetBoxedType(); _isConstant = true; if (dateFormatParameter != null) { if (_sourceType != typeof(string)) { throw new ExprValidationException("Use of the '" + dateFormatParameter.ParameterName + "' named parameter requires a string-type input"); } if (_targetType == null) { try { _targetType = TypeHelper.GetTypeForSimpleName(typeIdentifier); } catch (TypeLoadException e) { // expected } } // dynamic or static date format String staticDateFormat = null; ExprEvaluator dynamicDateFormat = null; Boolean iso8601Format = false; if (!dateFormatParameter.ChildNodes[0].IsConstantResult) { dynamicDateFormat = dateFormatParameter.ChildNodes[0].ExprEvaluator; } else { staticDateFormat = (string)dateFormatParameter.ChildNodes[0].ExprEvaluator.Evaluate( new EvaluateParams(null, true, validationContext.ExprEvaluatorContext)); if (staticDateFormat.ToLower().Trim() == "iso") { iso8601Format = true; } else { try { DateTime dateTimeTemp; DateTime.TryParseExact("", staticDateFormat, null, DateTimeStyles.None, out dateTimeTemp); //new SimpleDateFormat(staticDateFormat); } catch (Exception ex) { throw new ExprValidationException( "Invalid date format '" + staticDateFormat + "': " + ex.Message, ex); } } } if (_targetType == typeof(DateTime?) || typeIdentifier.ToLower() == "date") { _targetType = typeof(DateTime?); if (staticDateFormat != null) { if (iso8601Format) { _typeCaster = StringToDateTimeWStaticISOFormatComputer(); } else { _typeCaster = StringToDateTimeWStaticFormatComputer(staticDateFormat, validationContext.EngineImportService.TimeZone); } } else { _typeCaster = StringToDateTimeWDynamicFormatComputer(dynamicDateFormat, validationContext.EngineImportService.TimeZone); _isConstant = false; } } else if (_targetType == typeof(long?)) { _targetType = typeof(long?); if (staticDateFormat != null) { if (iso8601Format) { _typeCaster = StringToLongWStaticISOFormatComputer(); } else { _typeCaster = StringToLongWStaticFormatComputer(staticDateFormat, validationContext.EngineImportService.TimeZone); } } else { _typeCaster = StringToLongWDynamicFormatComputer(dynamicDateFormat, validationContext.EngineImportService.TimeZone); _isConstant = false; } } else { throw new ExprValidationException("Use of the '" + dateFormatParameter.ParameterName + "' named parameter requires a target type of datetime or long"); } } else if (_targetType == null) { try { _targetType = TypeHelper.ResolveType(_typeIdentifier, true); } catch (Exception e) { throw new ExprValidationException( "Type as listed in cast function by name '" + _typeIdentifier + "' cannot be loaded", e); } } _sourceType = _sourceType.GetBoxedType(); _targetType = _targetType.GetBoxedType(); if (_typeCaster != null) { // no-op } else if (_sourceType == _targetType) { _typeCaster = (o, evaluateParams) => o; } else if (_targetType == typeof(string)) { _typeCaster = (o, evaluateParams) => Convert.ToString(o); } else if (_sourceType == typeof(string)) { var typeParser = SimpleTypeParserFactory.GetParser(_targetType); _typeCaster = (o, evaluateParams) => typeParser((string)o); } else { var typeCaster = CastHelper.GetTypeCaster(_sourceType, _targetType); _typeCaster = (o, evaluateParams) => typeCaster.Invoke(o); } // determine constant or not // - basically, if the terms are constant then the cast can be computed now and stored away // - for future use. if (_isConstant && ChildNodes[0].IsConstantResult) { var evaluateParams = new EvaluateParams(null, true, validationContext.ExprEvaluatorContext); var inputValue = valueEvaluator.Evaluate(evaluateParams); var constantValue = _typeCaster.Invoke(inputValue, evaluateParams); _exprEvaluator = new ExprCastNodeConstEval(this, constantValue); } else { _exprEvaluator = new ExprCastNodeNonConstEval(this, valueEvaluator, _typeCaster); } return(null); }