public override ExprNode Validate(ExprValidationContext validationContext) { if (ChildNodes.Count == 0 || ChildNodes.Count > 2) { throw new ExprValidationException("Cast function node must have one or two child expressions"); } var valueEvaluator = ChildNodes[0].ExprEvaluator; var fromType = valueEvaluator.ReturnType; // determine date format parameter var namedParams = ExprNodeUtility.GetNamedExpressionsHandleDups(ChildNodes); ExprNodeUtility.ValidateNamed(namedParams, new string[] { "dateformat" }); var dateFormatParameter = namedParams.Get("dateformat"); if (dateFormatParameter != null) { ExprNodeUtility.ValidateNamedExpectType( dateFormatParameter, new Type[] { typeof(string) }); } // identify target type // try the primitive names including "string" _targetType = TypeHelper.GetPrimitiveTypeForName(_classIdentifier.Trim()).GetBoxedType(); SimpleTypeCaster caster; bool numeric; CasterParserComputer casterParserComputer = null; var classIdentifierInvariant = _classIdentifier.Trim().ToLowerInvariant(); if (dateFormatParameter != null) { if (fromType != typeof(string)) { throw new ExprValidationException( string.Format("Use of the '{0}' named parameter requires a string-type input", dateFormatParameter.ParameterName)); } if (_targetType == null) { try { _targetType = TypeHelper.GetClassForName( _classIdentifier.Trim(), validationContext.EngineImportService.GetClassForNameProvider()); } catch (TypeLoadException) { // expected } } // dynamic or static date format numeric = false; caster = null; StringToDateTimeBaseComputer dateTimeComputer; if (_targetType == typeof(DateTime) || _targetType == typeof(DateTime?) || classIdentifierInvariant.Equals("date")) { _targetType = typeof(DateTime); var desc = ValidateDateFormat(dateFormatParameter, validationContext); if (desc.StaticDateFormat != null) { if (desc.Iso8601Format) { dateTimeComputer = new StringToDateTimeWStaticISOFormatComputer(validationContext.EngineImportService.TimeZone); dateTimeComputer.HandleParseException += HandleParseISOException; } else { dateTimeComputer = new StringToDateTimeWStaticFormatComputer(desc.StaticDateFormat); dateTimeComputer.HandleParseException += HandleParseException; } } else { dateTimeComputer = new StringToDateTimeWDynamicFormatComputer(desc.DynamicDateFormat); dateTimeComputer.HandleParseException += HandleParseException; } } else if (_targetType == typeof(DateTimeOffset) || _targetType == typeof(DateTimeOffset?) || classIdentifierInvariant.Equals("dto") || classIdentifierInvariant.Equals("datetimeoffset")) { _targetType = typeof(DateTimeOffset); var desc = ValidateDateFormat(dateFormatParameter, validationContext); if (desc.StaticDateFormat != null) { if (desc.Iso8601Format) { dateTimeComputer = new StringToDtoWStaticISOFormatComputer(validationContext.EngineImportService.TimeZone); dateTimeComputer.HandleParseException += HandleParseISOException; } else { dateTimeComputer = new StringToDtoWStaticFormatComputer(desc.StaticDateFormat, validationContext.EngineImportService.TimeZone); dateTimeComputer.HandleParseException += HandleParseException; } } else { dateTimeComputer = new StringToDtoWDynamicFormatComputer(desc.DynamicDateFormat, validationContext.EngineImportService.TimeZone); dateTimeComputer.HandleParseException += HandleParseException; } } else if (_targetType == typeof(DateTimeEx) || classIdentifierInvariant.Equals("dtx") || classIdentifierInvariant.Equals("datetimeex") || classIdentifierInvariant.Equals("calendar")) { _targetType = typeof(DateTimeEx); var desc = ValidateDateFormat(dateFormatParameter, validationContext); if (desc.StaticDateFormat != null) { if (desc.Iso8601Format) { dateTimeComputer = new StringToDtxWStaticISOFormatComputer(validationContext.EngineImportService.TimeZone); dateTimeComputer.HandleParseException += HandleParseISOException; } else { dateTimeComputer = new StringToDtxWStaticFormatComputer(desc.StaticDateFormat, validationContext.EngineImportService.TimeZone); dateTimeComputer.HandleParseException += HandleParseException; } } else { dateTimeComputer = new StringToDtxWDynamicFormatComputer(desc.DynamicDateFormat, validationContext.EngineImportService.TimeZone); dateTimeComputer.HandleParseException += HandleParseException; } } else if (_targetType == typeof(long) || _targetType == typeof(long?)) { _targetType = typeof(long); var desc = ValidateDateFormat(dateFormatParameter, validationContext); if (desc.StaticDateFormat != null) { if (desc.Iso8601Format) { dateTimeComputer = new StringToDateTimeLongWStaticISOFormatComputer(validationContext.EngineImportService.TimeZone); dateTimeComputer.HandleParseException += HandleParseISOException; } else { dateTimeComputer = new StringToDateTimeLongWStaticFormatComputer(desc.StaticDateFormat); dateTimeComputer.HandleParseException += HandleParseException; } } else { dateTimeComputer = new StringToDateTimeLongWDynamicFormatComputer(desc.DynamicDateFormat); dateTimeComputer.HandleParseException += HandleParseException; } } else { throw new ExprValidationException( "Use of the '" + dateFormatParameter.ParameterName + "' named parameter requires a target type of long or datetime"); } casterParserComputer = dateTimeComputer; } else if (_targetType != null) { _targetType = _targetType.GetBoxedType(); caster = SimpleTypeCasterFactory.GetCaster(fromType, _targetType); numeric = _targetType.IsNumeric(); } else if (String.Equals(classIdentifierInvariant, "bigint", StringComparison.InvariantCultureIgnoreCase) || String.Equals(classIdentifierInvariant, "biginteger", StringComparison.InvariantCultureIgnoreCase)) { _targetType = typeof(BigInteger); caster = SimpleTypeCasterFactory.GetCaster(fromType, _targetType); numeric = true; } else if (classIdentifierInvariant.Equals("decimal".ToLowerInvariant())) { _targetType = typeof(decimal); caster = SimpleTypeCasterFactory.GetCaster(fromType, _targetType); numeric = true; } else { try { _targetType = TypeHelper.GetClassForName( _classIdentifier.Trim(), validationContext.EngineImportService.GetClassForNameProvider()); } catch (TypeLoadException e) { throw new ExprValidationException( "Type as listed in cast function by name '" + _classIdentifier + "' cannot be loaded", e); } numeric = _targetType.IsNumeric(); caster = numeric ? SimpleTypeCasterFactory.GetCaster(fromType, _targetType) : SimpleTypeCasterFactory.GetCaster(_targetType); } // assign a computer unless already assigned if (casterParserComputer == null) { // to-string if (_targetType == typeof(string)) { casterParserComputer = new StringXFormComputer(); } else if (fromType == typeof(string)) { // parse var parser = SimpleTypeParserFactory.GetParser(_targetType.GetBoxedType()); casterParserComputer = new StringParserComputer(parser); } else if (numeric) { // numeric cast with check casterParserComputer = new NumericCasterComputer(caster); } else { // non-numeric cast casterParserComputer = new NonnumericCasterComputer(caster); } } // determine constant or not Object theConstant = null; if (ChildNodes[0].IsConstantResult) { _isConstant = casterParserComputer.IsConstantForConstInput; if (_isConstant) { var evaluateParams = new EvaluateParams(null, true, validationContext.ExprEvaluatorContext); var @in = valueEvaluator.Evaluate(evaluateParams); theConstant = @in == null ? null : casterParserComputer.Compute(@in, evaluateParams); } } // determine evaluator if (_isConstant) { _exprEvaluator = new ExprCastNodeConstEval(this, theConstant); } else { _exprEvaluator = new ExprCastNodeNonConstEval(this, valueEvaluator, casterParserComputer); } return(null); }
internal ExprCastNodeNonConstEval(ExprCastNode parent, ExprEvaluator evaluator, CasterParserComputer casterParserComputer) { _parent = parent; _evaluator = evaluator; _casterParserComputer = casterParserComputer; }