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 fromType = ChildNodes[0].Forge.EvaluationType; var classIdentifier = ClassIdentifierWArray.ClassIdentifier; var classIdentifierInvariant = classIdentifier.Trim(); var arrayDimensions = ClassIdentifierWArray.ArrayDimensions; // Local function to match a class identifier bool MatchesClassIdentifier(string identifier) { return string.Equals( classIdentifierInvariant, identifier, StringComparison.InvariantCultureIgnoreCase); } // determine date format parameter var namedParams = ExprNodeUtilityValidate.GetNamedExpressionsHandleDups(ChildNodes); ExprNodeUtilityValidate.ValidateNamed(namedParams, new[] {"dateformat"}); var dateFormatParameter = namedParams.Get("dateformat"); if (dateFormatParameter != null) { ExprNodeUtilityValidate.ValidateNamedExpectType( dateFormatParameter, new[] { typeof(string), typeof(DateFormat), typeof(DateTimeFormat) }); } // identify target type // try the primitive names including "string" SimpleTypeCaster caster; var targetType = TypeHelper.GetPrimitiveTypeForName(classIdentifier.Trim()); if (!ClassIdentifierWArray.IsArrayOfPrimitive) { targetType = targetType.GetBoxedType(); } targetType = ApplyDimensions(targetType); bool numeric; CasterParserComputerForge casterParserComputerForge = null; if (dateFormatParameter != null) { if (fromType != typeof(string)) { throw new ExprValidationException( "Use of the '" + dateFormatParameter.ParameterName + "' named parameter requires a string-type input"); } if (targetType == null) { try { targetType = TypeHelper.GetClassForName( classIdentifier.Trim(), validationContext.ImportService.ClassForNameProvider); targetType = ApplyDimensions(targetType); } catch (TypeLoadException) { // expected } } // dynamic or static date format numeric = false; caster = null; if (targetType == typeof(DateTimeEx) || MatchesClassIdentifier("calendar") || MatchesClassIdentifier("dateTimeEx")) { targetType = typeof(DateTimeEx); var desc = ValidateDateFormat(dateFormatParameter, validationContext); if (desc.IsIso8601Format) { casterParserComputerForge = new StringToDateTimeExIsoFormatComputer(); } else if (desc.StaticDateFormat != null) { casterParserComputerForge = new StringToDateTimExWStaticFormatComputer( desc.StaticDateFormat, TimeZoneInfo.Utc); // Note how code-generation does not use the default time zone } else { casterParserComputerForge = new StringToDateTimeExWExprFormatComputer( desc.DynamicDateFormat, TimeZoneInfo.Utc); } } else if (targetType == typeof(DateTimeOffset) || targetType == typeof(DateTimeOffset?) || MatchesClassIdentifier("dto") || MatchesClassIdentifier("datetimeoffset")) { targetType = typeof(DateTimeOffset); var desc = ValidateDateFormat(dateFormatParameter, validationContext); if (desc.IsIso8601Format) { casterParserComputerForge = new StringToDateTimeOffsetIsoFormatComputer(); } else if (desc.StaticDateFormat != null) { casterParserComputerForge = new StringToDateTimeOffsetWStaticFormatComputer(desc.StaticDateFormat); } else { casterParserComputerForge = new StringToDateTimeOffsetWExprFormatComputerForge(desc.DynamicDateFormat); } } else if (targetType == typeof(DateTime) || targetType == typeof(DateTime?) || MatchesClassIdentifier("datetime")) { targetType = typeof(DateTime); var desc = ValidateDateFormat(dateFormatParameter, validationContext); if (desc.IsIso8601Format) { casterParserComputerForge = new StringToDateTimeIsoFormatComputer(); } else if (desc.StaticDateFormat != null) { casterParserComputerForge = new StringToDateTimeWStaticFormatComputer(desc.StaticDateFormat); } else { casterParserComputerForge = new StringToDateTimeWExprFormatComputerForge(desc.DynamicDateFormat); } } else if (targetType == typeof(long) || targetType == typeof(long?)) { targetType = typeof(long); var desc = ValidateDateFormat(dateFormatParameter, validationContext); if (desc.IsIso8601Format) { casterParserComputerForge = new StringToLongWStaticISOFormatComputer(); } else if (desc.StaticDateFormat != null) { casterParserComputerForge = new StringToLongWStaticFormatComputer(desc.StaticDateFormat); } else { casterParserComputerForge = new StringToLongWExprFormatComputerForge(desc.DynamicDateFormat); } } else { throw new ExprValidationException( "Use of the '" + dateFormatParameter.ParameterName + "' named parameter requires a target type of long, DateTime, DateTimeOffset or DateEx"); } } else if (targetType != null) { targetType = targetType.GetBoxedType(); caster = SimpleTypeCasterFactory.GetCaster(fromType, targetType); numeric = caster.IsNumericCast; } else if (MatchesClassIdentifier("bigint") || MatchesClassIdentifier("biginteger")) { targetType = typeof(BigInteger); targetType = ApplyDimensions(targetType); caster = SimpleTypeCasterFactory.GetCaster(fromType, targetType); numeric = true; } else if (MatchesClassIdentifier("decimal")) { targetType = typeof(decimal); targetType = ApplyDimensions(targetType); caster = SimpleTypeCasterFactory.GetCaster(fromType, targetType); numeric = true; } else { try { targetType = TypeHelper.GetClassForName( classIdentifier.Trim(), validationContext.ImportService.ClassForNameProvider); } catch (TypeLoadException e) { throw new ExprValidationException( "Class as listed in cast function by name '" + classIdentifier + "' cannot be loaded", e); } targetType = ApplyDimensions(targetType); numeric = targetType.IsNumeric(); if (numeric) { caster = SimpleTypeCasterFactory.GetCaster(fromType, targetType); } else { caster = new SimpleTypeCasterAnyType(targetType); } } // assign a computer unless already assigned if (casterParserComputerForge == null) { // to-string if (targetType == typeof(string)) { casterParserComputerForge = new StringXFormComputer(); } else if (fromType == typeof(string) && targetType != typeof(char)) { // parse SimpleTypeParserSPI parser = SimpleTypeParserFactory.GetParser(targetType.GetBoxedType()); casterParserComputerForge = new StringParserComputer(parser); } else if (numeric) { // numeric cast with check casterParserComputerForge = new NumberCasterComputer(caster); } else { // non-numeric cast casterParserComputerForge = new NonnumericCasterComputer(caster); } } // determine constant or not object theConstant = null; var isConstant = false; if (ChildNodes[0].Forge.ForgeConstantType.IsCompileTimeConstant) { isConstant = casterParserComputerForge.IsConstantForConstInput; if (isConstant) { var @in = ChildNodes[0].Forge.ExprEvaluator.Evaluate(null, true, null); theConstant = @in == null ? null : casterParserComputerForge.EvaluatorComputer.Compute(@in, null, true, null); } } forge = new ExprCastNodeForge(this, casterParserComputerForge, targetType, isConstant, theConstant); return null; }
public void SetObserverParameters( IList<ExprNode> parameters, MatchedEventConvertorForge convertor, ExprValidationContext validationContext) { this.convertor = convertor; // obtains name parameters IDictionary<string, ExprNamedParameterNode> namedExpressions; try { namedExpressions = ExprNodeUtilityValidate.GetNamedExpressionsHandleDups(parameters); ExprNodeUtilityValidate.ValidateNamed(namedExpressions, NAMED_PARAMETERS); } catch (ExprValidationException e) { throw new ObserverParameterException(e.Message, e); } var isoStringExpr = namedExpressions.Get(ISO_NAME); if (namedExpressions.Count == 1 && isoStringExpr != null) { try { allConstantResult = ExprNodeUtilityValidate.ValidateNamedExpectType( isoStringExpr, new[] {typeof(string)}); } catch (ExprValidationException ex) { throw new ObserverParameterException(ex.Message, ex); } scheduleComputer = new TimerScheduleSpecComputeISOStringForge(isoStringExpr.ChildNodes[0]); } else if (isoStringExpr != null) { throw new ObserverParameterException( "The '" + ISO_NAME + "' parameter is exclusive of other parameters"); } else if (namedExpressions.Count == 0) { throw new ObserverParameterException("No parameters provided"); } else { allConstantResult = true; var dateNamedNode = namedExpressions.Get(DATE_NAME); var repetitionsNamedNode = namedExpressions.Get(REPETITIONS_NAME); var periodNamedNode = namedExpressions.Get(PERIOD_NAME); if (dateNamedNode == null && periodNamedNode == null) { throw new ObserverParameterException("Either the date or period parameter is required"); } try { if (dateNamedNode != null) { allConstantResult = ExprNodeUtilityValidate.ValidateNamedExpectType( dateNamedNode, new[] { typeof(string), typeof(DateTimeEx), typeof(DateTimeOffset), typeof(DateTime), typeof(long) }); } if (repetitionsNamedNode != null) { allConstantResult &= ExprNodeUtilityValidate.ValidateNamedExpectType( repetitionsNamedNode, new[] {typeof(int), typeof(long)}); } if (periodNamedNode != null) { allConstantResult &= ExprNodeUtilityValidate.ValidateNamedExpectType( periodNamedNode, new[] {typeof(TimePeriod)}); } } catch (ExprValidationException ex) { throw new ObserverParameterException(ex.Message, ex); } var dateNode = dateNamedNode == null ? null : dateNamedNode.ChildNodes[0]; var repetitionsNode = repetitionsNamedNode == null ? null : repetitionsNamedNode.ChildNodes[0]; var periodNode = periodNamedNode == null ? null : (ExprTimePeriod) periodNamedNode.ChildNodes[0]; scheduleComputer = new TimerScheduleSpecComputeFromExprForge(dateNode, repetitionsNode, periodNode); } if (allConstantResult) { try { scheduleComputer.VerifyComputeAllConst(validationContext); } catch (ScheduleParameterException ex) { throw new ObserverParameterException(ex.Message, ex); } } }