예제 #1
0
        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);
        }
예제 #2
0
 internal ExprCastNodeNonConstEval(ExprCastNode parent, ExprEvaluator evaluator, CasterParserComputer casterParserComputer)
 {
     _parent               = parent;
     _evaluator            = evaluator;
     _casterParserComputer = casterParserComputer;
 }