Пример #1
0
        public PropertyValidator()
        {
            this.RuleFor(x => x.Name).NotEmpty().WithMessage(Config.ValidationMessages.NAME_CANT_BE_EMPTY);
            this.RuleFor(x => x.Name).Must(EnumerationValidator.IsStartNotWithDigit).WithMessage(Config.ValidationMessages.NAME_START_WITH_DIGIT);
            this.RuleFor(x => x.Name).Must(EnumerationValidator.IsNotContainsSpace).WithMessage(Config.ValidationMessages.NAME_CANT_CONTAINS_SPACE);
            this.RuleFor(x => x.Name).Custom((name, cntx) =>
            {
                var p = (Property)cntx.InstanceToValidate;
                if (p.Parent == null)
                {
                    return;
                }
                var pg = (GroupListProperties)p.Parent;
                //if (pg.Parent == null)
                //    return;
                if (pg.Parent is Catalog)
                {
                    var c     = (Catalog)pg.Parent;
                    var gc    = (IGroupListCatalogs)c.Parent;
                    var model = (IModel)gc.Parent;
                    if (model.DbSettings.PKeyName == name)
                    {
                        var vf = new ValidationFailure(nameof(p.Name),
                                                       $"Model DbSettings parameter 'PKeyName' is set to '{name}'. This Property name is reserved for auto generated ID property");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                    ValidateSpecialProperties(name, cntx, p, c, gc);
                    if (c.UseTree && !c.UseSeparatePropertiesForGroups && c.UseFolderTypeExplicitly)
                    {
                        if (gc.PropertyIsFolderName == name)
                        {
                            var vf = new ValidationFailure(nameof(p.Name),
                                                           $"Catalog parameter 'UseFolderTypeExplicitly' is set to 'true'. Property name '{gc.PropertyIsFolderName}' is reserved for auto generated property");
                            vf.Severity = Severity.Error;
                            cntx.AddFailure(vf);
                        }
                        if (gc.PropertyIsOpenName == name)
                        {
                            var vf = new ValidationFailure(nameof(p.Name),
                                                           $"Catalog parameter 'UseFolderTypeExplicitly' is set to 'true'. Property name '{gc.PropertyIsOpenName}' is reserved for auto generated property");
                            vf.Severity = Severity.Error;
                            cntx.AddFailure(vf);
                        }
                    }
                }
                else if (pg.Parent is CatalogFolder)
                {
                    var c   = (Catalog)pg.Parent.Parent;
                    var gc  = (IGroupListCatalogs)c.Parent;
                    var cfg = pg.GetConfig();
                    if (cfg.Model.DbSettings.PKeyName == name)
                    {
                        var vf = new ValidationFailure(nameof(p.Name),
                                                       $"Model DbSettings parameter 'PKeyName' is set to '{name}'. This Property name is reserved for auto generated ID property");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                    ValidateSpecialProperties(name, cntx, p, c, gc);
                    if (c.UseTree && !c.UseSeparatePropertiesForGroups && c.UseFolderTypeExplicitly)
                    {
                        if (gc.PropertyIsOpenName == name)
                        {
                            var vf = new ValidationFailure(nameof(p.Name),
                                                           $"Catalog parameter 'UseFolderTypeExplicitly' is set to 'true'. Property name '{gc.PropertyIsOpenName}' is reserved for auto generated property");
                            vf.Severity = Severity.Error;
                            cntx.AddFailure(vf);
                        }
                    }
                }
                else if (pg.Parent is PropertiesTab)
                {
                    var cfg = pg.GetConfig();
                    if (cfg.Model.DbSettings.PKeyName == name)
                    {
                        var vf = new ValidationFailure(nameof(p.Name),
                                                       $"Model DbSettings parameter 'PKeyName' is set to '{name}'. This Property name is reserved for auto generated ID property");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                }
                else if (pg.Parent is Document)
                {
                }
                else if (pg.Parent is GroupDocuments)
                {
                }
                else
                {
                    Debug.Assert(false);
                    throw new NotImplementedException();
                }
                foreach (var t in pg.ListProperties)
                {
                    if ((p.Guid != t.Guid) && (name == t.Name))
                    {
                        var vf = new ValidationFailure(nameof(p.Name),
                                                       $"Not unique property name '{name}'");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                }
            });

            this.RuleFor(x => x.Length).Custom((name, cntx) =>
            {
                var p = (Property)cntx.InstanceToValidate;
                if (p.DataTypeEnum == EnumDataType.STRING)
                {
                    if (!string.IsNullOrWhiteSpace(p.MinLengthRequirement))
                    {
                        BigInteger vmin;
                        if (BigInteger.TryParse(p.MinLengthRequirement, out vmin))
                        {
                            if (p.Length <= vmin)
                            {
                                var vf = new ValidationFailure(nameof(p.Length),
                                                               $"Value less or equal than {nameof(p.MinLengthRequirement)} property value");
                                vf.Severity = Severity.Error;
                                cntx.AddFailure(vf);
                            }
                        }
                    }
                    if (!string.IsNullOrWhiteSpace(p.MaxLengthRequirement))
                    {
                        BigInteger vmax;
                        if (BigInteger.TryParse(p.MaxLengthRequirement, out vmax))
                        {
                            if (p.Length <= vmax)
                            {
                                var vf = new ValidationFailure(nameof(p.Length),
                                                               $"Value less or equal than {nameof(p.MaxLengthRequirement)} property value");
                                vf.Severity = Severity.Error;
                                cntx.AddFailure(vf);
                            }
                        }
                    }
                }
                else if (p.DataTypeEnum == EnumDataType.NUMERICAL)
                {
                    if (p.Length <= p.Accuracy)
                    {
                        var vf = new ValidationFailure(nameof(p.Length),
                                                       $"Value less or equal than {nameof(p.Accuracy)} property value");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                    if (p.Length > 38)
                    {
                        var vf = new ValidationFailure(nameof(p.Length),
                                                       $"Value greater than 38 is not supported");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                }
            });
            this.RuleFor(x => x.Accuracy).Custom((name, cntx) =>
            {
                var p = (Property)cntx.InstanceToValidate;
                if (p.DataTypeEnum != EnumDataType.NUMERICAL)
                {
                    return;
                }
                if (p.IsPositive)
                {
                    return;
                }
                if (p.Accuracy >= p.Length)
                {
                    var vf = new ValidationFailure(nameof(p.Accuracy),
                                                   $"Value greater or equal than {nameof(p.Length)} property value");
                    vf.Severity = Severity.Error;
                    cntx.AddFailure(vf);
                }
            });

            this.RuleFor(x => x.MinLengthRequirement).Custom((name, cntx) =>
            {
                var p = (Property)cntx.InstanceToValidate;
                if (p.DataTypeEnum != EnumDataType.STRING)
                {
                    return;
                }
                if (string.IsNullOrWhiteSpace(p.MinLengthRequirement))
                {
                    return;
                }
                BigInteger vmin;
                if (!BigInteger.TryParse(p.MinLengthRequirement, out vmin))
                {
                    var vf = new ValidationFailure(nameof(p.MinLengthRequirement),
                                                   $"Can't parse to INTEGER");
                    vf.Severity = Severity.Error;
                    cntx.AddFailure(vf);
                    return;
                }
                if (vmin >= p.Length)
                {
                    var vf = new ValidationFailure(nameof(p.MinLengthRequirement),
                                                   $"Value greater or equal than {nameof(p.Length)} property value");
                    vf.Severity = Severity.Error;
                    cntx.AddFailure(vf);
                }
                if (string.IsNullOrWhiteSpace(p.MaxLengthRequirement))
                {
                    return;
                }
                BigInteger vmax;
                if (BigInteger.TryParse(p.MaxLengthRequirement, out vmax))
                {
                    if (vmin >= vmax)
                    {
                        var vf = new ValidationFailure(nameof(p.MinLengthRequirement),
                                                       $"Value greater or equal than {nameof(p.MaxLengthRequirement)} property value");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                }
            });
            this.RuleFor(x => x.MaxLengthRequirement).Custom((name, cntx) =>
            {
                var p = (Property)cntx.InstanceToValidate;
                if (p.DataTypeEnum != EnumDataType.STRING)
                {
                    return;
                }
                if (string.IsNullOrWhiteSpace(p.MaxLengthRequirement))
                {
                    return;
                }
                BigInteger vmax;
                if (!BigInteger.TryParse(p.MaxLengthRequirement, out vmax))
                {
                    var vf = new ValidationFailure(nameof(p.MaxLengthRequirement),
                                                   $"Can't parse to INTEGER");
                    vf.Severity = Severity.Error;
                    cntx.AddFailure(vf);
                    return;
                }
                if (vmax >= p.Length)
                {
                    var vf = new ValidationFailure(nameof(p.MaxLengthRequirement),
                                                   $"Value greater or equal than {nameof(p.Length)} property value");
                    vf.Severity = Severity.Error;
                    cntx.AddFailure(vf);
                }
                if (string.IsNullOrWhiteSpace(p.MinLengthRequirement))
                {
                    return;
                }
                BigInteger vmin;
                if (BigInteger.TryParse(p.MinLengthRequirement, out vmin))
                {
                    if (vmin >= vmax)
                    {
                        var vf = new ValidationFailure(nameof(p.MaxLengthRequirement),
                                                       $"Value less or equal than {nameof(p.MinLengthRequirement)} property value");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                }
            });
            this.RuleFor(x => x.RangeValuesRequirementStr).Custom((x, cntx) =>
            {
                var p = (Property)cntx.InstanceToValidate;
                ValidateRangeValuesRequirements(cntx, p);
            });

            this.RuleFor(x => x.DefaultValue).Custom((x, cntx) =>
            {
                if (string.IsNullOrWhiteSpace(x))
                {
                    return;
                }
                var val = x.Trim();
                var p   = (Property)cntx.InstanceToValidate;
                switch (p.DataType.DataTypeEnum)
                {
                case EnumDataType.BOOL:
                    if (!bool.TryParse(val, out bool v))
                    {
                        var vf = new ValidationFailure(nameof(p.DefaultValue),
                                                       $"Can't parse by bool.Parse() default property value");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                    break;

                case EnumDataType.CHAR:
                    if (val[0] != '\'')
                    {
                        var vf = new ValidationFailure(nameof(p.DefaultValue),
                                                       $"Char value has to start with \' character");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                    if (val[val.Length - 1] != '\'')
                    {
                        var vf = new ValidationFailure(nameof(p.DefaultValue),
                                                       $"Char value has to finish with \' character");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                    if (val.Length != 3)
                    {
                        var vf = new ValidationFailure(nameof(p.DefaultValue),
                                                       $"Char value has to follow next format 'a'");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                    break;

                case EnumDataType.DATE:
#if !NET6_0
                    if (!DateTime.TryParse(val, out DateTime vd))
                    {
                        var vf = new ValidationFailure(nameof(p.DefaultValue),
                                                       $"Can't parse by DateOnly.Parse() default property value");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
#else
                    if (!DateOnly.TryParse(val, out DateOnly vd))
                    {
                        var vf = new ValidationFailure(nameof(p.DefaultValue),
                                                       $"Can't parse by DateOnly.Parse() default property value");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
#endif
                    break;

                case EnumDataType.DATETIMELOCAL:
                case EnumDataType.DATETIMEUTC:
                    //case EnumDataType.DATETIMEZ:
                    if (!DateTime.TryParse(val, out DateTime vdt))
                    {
                        var vf = new ValidationFailure(nameof(p.DefaultValue),
                                                       $"Can't parse by DateTime.Parse() default property value");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                    break;

                case EnumDataType.TIME:
#if !NET6_0
                    if (!DateTime.TryParse(val, out DateTime vt))
                    {
                        var vf = new ValidationFailure(nameof(p.DefaultValue),
                                                       $"Can't parse by DateOnly.Parse() default property value");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
#else
                    if (!TimeOnly.TryParse(val, out TimeOnly vt))
                    {
                        var vf = new ValidationFailure(nameof(p.DefaultValue),
                                                       $"Can't parse by TimeOnly.Parse() default property value");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
#endif
                    break;

                case EnumDataType.STRING:
                    if (val[0] != '\"')
                    {
                        var vf = new ValidationFailure(nameof(p.DefaultValue),
                                                       $"String value has to start with \" character");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                    if (val[val.Length - 1] != '\"')
                    {
                        var vf = new ValidationFailure(nameof(p.DefaultValue),
                                                       $"String value has to finish with \" character");
                        vf.Severity = Severity.Error;
                        cntx.AddFailure(vf);
                    }
                    break;

                default:
                    break;
                }
            });

            #region ObjectGuid
            this.RuleFor(p => p.ObjectGuid).Must((p, y) =>
            {
                if (p.DataTypeEnum == EnumDataType.ENUMERATION && string.IsNullOrWhiteSpace(p.ObjectGuid))
                {
                    return(false);
                }

                return(true);
            }).WithMessage(Config.ValidationMessages.TYPE_EMPTY_ENUMERATION);
            this.RuleFor(p => p.ObjectGuid).Must((p, y) =>
            {
                if (p.DataTypeEnum == EnumDataType.CATALOG && string.IsNullOrWhiteSpace(p.ObjectGuid))
                {
                    return(false);
                }

                return(true);
            }).WithMessage(Config.ValidationMessages.TYPE_EMPTY_CATALOG);
            this.RuleFor(p => p.ObjectGuid).Must((p, y) =>
            {
                if (p.DataTypeEnum == EnumDataType.DOCUMENT && string.IsNullOrWhiteSpace(p.ObjectGuid))
                {
                    return(false);
                }

                return(true);
            }).WithMessage(Config.ValidationMessages.TYPE_EMPTY_DOCUMENT);
            this.RuleFor(p => p.ObjectGuid).Must((p, y) =>
            {
                if (p.DataTypeEnum != EnumDataType.ENUMERATION)
                {
                    return(true);
                }

                IParent n = (IParent)p;
                while (true)
                {
                    if (n.Parent != null)
                    {
                        n = n.Parent;
                        if (n is Config)
                        {
                            break;
                        }
                    }
                    else
                    {
                        return(true);
                    }
                }
                foreach (var t in (n as Config).Model.GroupEnumerations.ListEnumerations)
                {
                    if (t.Guid == y)
                    {
                        return(true);
                    }
                }
                return(false);
            }).WithMessage(Config.ValidationMessages.TYPE_OBJECT_IS_NOT_FOUND);
            this.RuleFor(p => p.ObjectGuid).Must((p, y) =>
            {
                if (p.DataTypeEnum != EnumDataType.CATALOG)
                {
                    return(true);
                }

                IParent n = (IParent)p;
                while (true)
                {
                    if (n.Parent != null)
                    {
                        n = n.Parent;
                        if (n is Config)
                        {
                            break;
                        }
                    }
                    else
                    {
                        return(true);
                    }
                }
                foreach (var t in (n as Config).Model.GroupCatalogs.ListCatalogs)
                {
                    if (t.Guid == y)
                    {
                        return(true);
                    }
                }
                return(false);
            }).WithMessage(Config.ValidationMessages.TYPE_OBJECT_IS_NOT_FOUND);
            this.RuleFor(p => p.ObjectGuid).Must((p, y) =>
            {
                if (p.DataTypeEnum != EnumDataType.DOCUMENT)
                {
                    return(true);
                }

                IParent n = (IParent)p;
                while (true)
                {
                    if (n.Parent != null)
                    {
                        n = n.Parent;
                        if (n is Config)
                        {
                            break;
                        }
                    }
                    else
                    {
                        return(true);
                    }
                }
                foreach (var t in (n as Config).Model.GroupDocuments.GroupListDocuments.ListDocuments)
                {
                    if (t.Guid == y)
                    {
                        return(true);
                    }
                }
                return(false);
            }).WithMessage(Config.ValidationMessages.TYPE_OBJECT_IS_NOT_FOUND);
            #endregion ObjectGuid

            #region Loose data
            this.RuleFor(x => x.DataTypeEnum).Custom((path, cntx) =>
            {
                var pg   = ((Property)cntx.InstanceToValidate).DataType;
                var prev = pg.PrevCurrentVersion();
                var ver  = "CURRENT";
                if (prev != null && pg.DataTypeEnum != prev.DataTypeEnum)
                {
                    var vf = new ValidationFailure(nameof(pg.DataTypeEnum),
                                                   $"Comparison with previous {ver} version. Data type was changed from '{Enum.GetName(typeof(EnumDataType), prev.DataTypeEnum)}' to '{Enum.GetName(typeof(EnumDataType), pg.DataTypeEnum)}'");
                    vf.Severity = Severity.Warning;
                    cntx.AddFailure(vf);
                }
                prev = pg.PrevStableVersion();
                ver  = "STABLE";
                if (prev != null && pg.DataTypeEnum != prev.DataTypeEnum)
                {
                    var vf = new ValidationFailure(nameof(pg.DataTypeEnum),
                                                   $"Comparison with previous {ver} version. Data type was changed from '{Enum.GetName(typeof(EnumDataType), prev.DataTypeEnum)}' to '{Enum.GetName(typeof(EnumDataType), pg.DataTypeEnum)}'");
                    vf.Severity = Severity.Warning;
                    cntx.AddFailure(vf);
                }
            });
            this.RuleFor(x => x.Length).Custom((path, cntx) =>
            {
                var pg   = ((Property)cntx.InstanceToValidate).DataType;
                var prev = pg.PrevCurrentVersion();
                var ver  = "CURRENT";
                if (prev != null && pg.DataTypeEnum == prev.DataTypeEnum)
                {
                    if (pg.Length > 0 && prev.Length > 0 && pg.Length < prev.Length)
                    {
                        var vf      = new ValidationFailure(nameof(pg.Length), $"Comparison with previous {ver} version. Length was reduced from '{prev.Length}' to '{pg.Length}'");
                        vf.Severity = Severity.Warning;
                        cntx.AddFailure(vf);
                    }
                    else if (pg.Length > 0 && prev.Length == 0)
                    {
                        var vf      = new ValidationFailure(nameof(pg.Length), $"Comparison with previous {ver} version. Length was reduced from 'MAX' to '{pg.Length}'");
                        vf.Severity = Severity.Warning;
                        cntx.AddFailure(vf);
                    }
                }
                prev = pg.PrevStableVersion();
                ver  = "STABLE";
                if (prev != null && pg.DataTypeEnum == prev.DataTypeEnum)
                {
                    if (pg.Length > 0 && prev.Length > 0 && pg.Length < prev.Length)
                    {
                        var vf      = new ValidationFailure(nameof(pg.Length), $"Comparison with previous {ver} version. Length was reduced from '{prev.Length}' to '{pg.Length}'");
                        vf.Severity = Severity.Warning;
                        cntx.AddFailure(vf);
                    }
                    else if (pg.Length > 0 && prev.Length == 0)
                    {
                        var vf      = new ValidationFailure(nameof(pg.Length), $"Comparison with previous {ver} version. Length was reduced from 'MAX' to '{pg.Length}'");
                        vf.Severity = Severity.Warning;
                        cntx.AddFailure(vf);
                        return;
                    }
                }
            });
            this.RuleFor(x => x.Accuracy).Custom((path, cntx) =>
            {
                var pg   = ((Property)cntx.InstanceToValidate).DataType;
                var prev = pg.PrevCurrentVersion();
                var ver  = "CURRENT";
                if (prev != null && pg.DataTypeEnum == prev.DataTypeEnum)
                {
                    if (pg.DataTypeEnum == EnumDataType.NUMERICAL)
                    {
                        if (pg.Accuracy < prev.Accuracy)
                        {
                            var vf      = new ValidationFailure(nameof(pg.Accuracy), $"Comparison with previous {ver} version. Accuracy was reduced from '{prev.Accuracy}' to '{pg.Accuracy}'");
                            vf.Severity = Severity.Warning;
                            cntx.AddFailure(vf);
                        }
                    }
                }
                prev = pg.PrevStableVersion();
                ver  = "STABLE";
                if (prev != null && pg.DataTypeEnum == prev.DataTypeEnum)
                {
                    if (pg.DataTypeEnum == EnumDataType.NUMERICAL)
                    {
                        if (pg.Accuracy < prev.Accuracy)
                        {
                            var vf      = new ValidationFailure(nameof(pg.Accuracy), $"Comparison with previous {ver} version. Accuracy was reduced from '{prev.Accuracy}' to '{pg.Accuracy}'");
                            vf.Severity = Severity.Warning;
                            cntx.AddFailure(vf);
                        }
                    }
                }
            });
            #endregion Loose data
        }