Beispiel #1
0
        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);
        }