Пример #1
0
    private static MapStringRequiredInfo _GetMapStringRequiredInfo(string defineString, FieldInfo fieldInfo, out string errorString)
    {
        // 对定义字符串进行词法解析,得到解析后的token列表
        List <MapStringToken> tokenList = _AnalyzeMapStringRequiredInfo(defineString, out errorString);

        if (errorString != null)
        {
            errorString = string.Concat("定义错误:", errorString);
            return(null);
        }

        if (tokenList.Count == 0)
        {
            errorString = "定义中未含有任何元素声明";
            return(null);
        }

        // 因为整个定义相当于一个map,故将上面得到的token列表首尾加上map开始和结束标记
        tokenList.Insert(0, new MapStringToken(MapStringTokenType.StartMap, "("));
        tokenList.Add(new MapStringToken(MapStringTokenType.EndMap, ")"));

        MapStringCheckRuleParser parser       = new MapStringCheckRuleParser();
        MapStringRequiredInfo    requiredInfo = parser.GetMapStringCheckRule(tokenList, fieldInfo.MapStringFormatDefine, out errorString);

        if (errorString == null)
        {
            return(requiredInfo);
        }
        else
        {
            errorString = string.Concat("定义错误:", errorString);
            return(null);
        }
    }
Пример #2
0
    public MapStringRequiredInfo GetMapStringCheckRule(List <MapStringToken> tokenList, MapStringInfo formatDefine, out string errorString)
    {
        _tokenQueue   = new Queue <MapStringToken>(tokenList);
        _formatDefine = formatDefine;

        MapStringRequiredInfo requiredInfo = _GetMap(out errorString);

        if (errorString == null)
        {
            return(requiredInfo);
        }
        else
        {
            return(null);
        }
    }
Пример #3
0
    private MapStringRequiredInfo _GetMap(out string errorString)
    {
        MapStringRequiredInfo requiredInfo = new MapStringRequiredInfo();

        // 跳过map结构开始的{
        _tokenQueue.Dequeue();

        _GetMapElement(requiredInfo, _formatDefine, out errorString);
        if (errorString == null)
        {
            return(requiredInfo);
        }
        else
        {
            errorString = string.Concat("解析map中的子元素错误:", errorString);
            return(null);
        }
    }
Пример #4
0
    private static bool _CheckMapStringData(JsonData jsonData, MapStringRequiredInfo requiredInfo, out string errorString)
    {
        List <string> errorStringList = new List <string>();

        foreach (MapStringParamRequiredInfo paramRequiredInfo in requiredInfo.ParamRequiredInfo.Values)
        {
            if (_CheckMapStringParamData(jsonData, paramRequiredInfo, out errorString) == false)
            {
                errorStringList.Add(errorString);
            }
        }

        if (errorStringList.Count == 0)
        {
            errorString = null;
            return(true);
        }
        else
        {
            errorString = Utils.CombineString(errorStringList, "\n");
            return(false);
        }
    }
Пример #5
0
    private void _GetMapElement(MapStringRequiredInfo requiredInfo, MapStringInfo formatDefine, out string errorString)
    {
        // 解析key
        if (_tokenQueue.Count == 0)
        {
            errorString = "定义不完整";
            return;
        }
        MapStringToken keyToken = _tokenQueue.Dequeue();

        if (keyToken.TokenType != MapStringTokenType.String)
        {
            errorString = string.Concat("map子元素中的key名非法,输入值为", keyToken.DefineString);
            return;
        }
        string key = keyToken.DefineString.Trim();

        // 检查该变量名是否定义
        if (!formatDefine.ParamInfo.ContainsKey(key))
        {
            errorString = string.Format("mapString定义中不存在名为{0}的key", key);
            return;
        }
        // 检查是否已存在此变量名
        MapStringParamInfo paramInfo = formatDefine.ParamInfo[key];

        if (requiredInfo.ParamRequiredInfo.ContainsKey(key))
        {
            errorString = string.Format("定义中存在相同的key名({0})", key);
            return;
        }

        // 判断key名后是否为等号
        if (_tokenQueue.Count == 0)
        {
            errorString = string.Format("定义不完整,map子元素中的key名({0})后缺失等号", key);
            return;
        }
        MapStringToken equalSignToken = _tokenQueue.Dequeue();

        if (equalSignToken.TokenType != MapStringTokenType.EqualSign)
        {
            errorString = string.Concat("map子元素中的key名({0})后应为等号,而输入值为{1}", key, equalSignToken.DefineString);
            return;
        }

        // 解析value值
        if (_tokenQueue.Count == 0)
        {
            errorString = string.Format("定义不完整,map子元素中的key名({0})在等号后未声明参数要求,请用1声明为必须存在或用0声明为不允许存在", key);
            return;
        }
        MapStringToken valueToken = _tokenQueue.Dequeue();

        if (valueToken.TokenType == MapStringTokenType.Number)
        {
            if ("1".Equals(valueToken.DefineString))
            {
                MapStringParamRequiredInfo paramRequiredInfo = new MapStringParamRequiredInfo();
                paramRequiredInfo.ParamName     = key;
                paramRequiredInfo.ParamRequired = ParamRequired.MustHave;

                requiredInfo.ParamRequiredInfo.Add(key, paramRequiredInfo);
            }
            else if ("0".Equals(valueToken.DefineString))
            {
                MapStringParamRequiredInfo paramRequiredInfo = new MapStringParamRequiredInfo();
                paramRequiredInfo.ParamName     = key;
                paramRequiredInfo.ParamRequired = ParamRequired.NotAllowed;

                requiredInfo.ParamRequiredInfo.Add(key, paramRequiredInfo);
            }
            else
            {
                errorString = string.Format("map子元素中的key名({0})对应的参数要求非法,输入值为\"{1}\",请用1或0分别设置该参数为必须含有或不允许含有", keyToken.DefineString);
                return;
            }
        }
        else if (valueToken.TokenType == MapStringTokenType.StartMap)
        {
            if (paramInfo.DataType == DataType.MapString)
            {
                MapStringRequiredInfo childRequiredInfo = new MapStringRequiredInfo();
                _GetMapElement(childRequiredInfo, formatDefine.ParamInfo[key].MapStringInfo, out errorString);
                if (errorString != null)
                {
                    errorString = string.Format("名为{0}的map下属的子元素错误:{1}", key, errorString);
                    return;
                }
                MapStringParamRequiredInfo paramRequiredInfo = new MapStringParamRequiredInfo();
                paramRequiredInfo.ParamName             = key;
                paramRequiredInfo.ParamRequired         = ParamRequired.None;
                paramRequiredInfo.MapStringRequiredInfo = childRequiredInfo;

                requiredInfo.ParamRequiredInfo.Add(key, paramRequiredInfo);
            }
            else
            {
                errorString = string.Format("mapString定义中要求key名({0})对应{1}类型的数据,而输入的检查规则却以mapString型进行设置,请不要对非mapString型使用括号声明", key, paramInfo.DataType);
                return;
            }
        }
        else
        {
            errorString = string.Format("map子元素中的key名({0})对应的参数要求非法,输入值为\"{1}\",请用1或0分别设置该参数为必须含有或不允许含有", keyToken.DefineString);
            return;
        }

        // 解析后面的token
        if (_tokenQueue.Count == 0)
        {
            errorString = string.Format("定义不完整,map下的子元素{0}之后未声明用英文逗号分隔下一个子元素,也没有声明map的结束", key);
            return;
        }
        MapStringToken nextToken = _tokenQueue.Dequeue();

        if (nextToken.TokenType == MapStringTokenType.EndMap)
        {
            errorString = null;
            return;
        }
        else if (nextToken.TokenType == MapStringTokenType.Comma)
        {
            if (_tokenQueue.Count == 0)
            {
                errorString = string.Format("定义不完整,map下的子元素{0}之后的英文逗号后未声明下一个元素", key);
                return;
            }
            _GetMapElement(requiredInfo, formatDefine, out errorString);
            if (errorString != null)
            {
                errorString = string.Format("名为{0}的子元素后面的元素声明错误:{1}", key, errorString);
                return;
            }
        }
        else
        {
            errorString = string.Format("map下的子元素{0}之后未声明用英文逗号分隔下一个子元素,也没有声明map的结束,输入值为{1}", key, nextToken.DefineString);
            return;
        }
    }
Пример #6
0
    /// <summary>
    /// 用于检查mapString型当逻辑上某列对应不同的类型取值时,其数据按是否要求含有或不允许有某些元素
    /// </summary>
    public static bool CheckMapString(FieldInfo fieldInfo, FieldCheckRule checkRule, out string errorString)
    {
        if (fieldInfo.DataType != DataType.MapString)
        {
            errorString = string.Format("mapString型的内容检查只适用于mapString类型的字段,要检查的这列类型为{0}\n", fieldInfo.DataType.ToString());
            return(false);
        }

        MapStringCheckRule mapStringCheckRule = new MapStringCheckRule();

        // 解析检查规则
        const string CHECK_RULE_START_STRING = "mapString:";
        string       checkRuleString         = null;

        if (checkRule.CheckRuleString.Equals(CHECK_RULE_START_STRING, StringComparison.CurrentCultureIgnoreCase))
        {
            errorString = "mapString型的内容检查规则声明中必须含有具体的检查规则\n";
            return(false);
        }
        else if (!checkRule.CheckRuleString.StartsWith(CHECK_RULE_START_STRING, StringComparison.CurrentCultureIgnoreCase))
        {
            errorString = string.Format("mapString型的内容检查规则声明错误,必须以\"{0}\"开头\n", CHECK_RULE_START_STRING);
            return(false);
        }
        else
        {
            checkRuleString = checkRule.CheckRuleString.Substring(CHECK_RULE_START_STRING.Length).Trim();
        }

        // 通过|分隔不同条件下的内容检查规则
        string[] checkRuleList = checkRuleString.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
        // 解析每一种条件下对应的mapString内容
        for (int i = 0; i < checkRuleList.Length; ++i)
        {
            // 条件解析
            MapStringCondition mapStringCondition = new MapStringCondition();

            string oneCheckRule  = checkRuleList[i].Trim();
            string tempCheckRule = oneCheckRule;
            if (string.IsNullOrEmpty(oneCheckRule))
            {
                errorString = "mapString型的内容检查规则声明错误,不允许含有空的规则声明,请检查是否含有多余的|分隔符\n";
                return(false);
            }

            const string IF_CONDITION_START_STRING = "if(";
            if (oneCheckRule.Equals(IF_CONDITION_START_STRING, StringComparison.CurrentCultureIgnoreCase) || !oneCheckRule.StartsWith(IF_CONDITION_START_STRING, StringComparison.CurrentCultureIgnoreCase))
            {
                errorString = string.Format("mapString型的内容检查规则声明错误,必须在if后面的括号中声明其他字段需满足的条件。若无要求,请填写为\"if(all)\",你填写的为{0}\n", oneCheckRule);
                return(false);
            }
            tempCheckRule = tempCheckRule.Substring(IF_CONDITION_START_STRING.Length);
            int rightBracket = tempCheckRule.IndexOf(')');
            if (rightBracket == -1)
            {
                errorString = string.Format("mapString型的内容检查规则声明错误,if后面的右括号缺失,你填写的为{0}\n", oneCheckRule);
                return(false);
            }
            if (rightBracket == tempCheckRule.Length - 1)
            {
                errorString = string.Format("mapString型的内容检查规则声明错误,在if后面的括号中声明其他字段需满足的条件之后,还需在方括号内声明对mapString型下属字段的要求\n", oneCheckRule);
                return(false);
            }
            string ifConditionString = tempCheckRule.Substring(0, rightBracket).Trim();
            if (string.IsNullOrEmpty(ifConditionString))
            {
                errorString = "mapString型的内容检查规则声明错误,if后的括号中为空,若要设置为在任何条件下,请填写为\"if(all)\"\n";
                return(false);
            }
            else if ("all".Equals(ifConditionString, StringComparison.CurrentCultureIgnoreCase))
            {
                Condition condition = new Condition();
                condition.FieldInfo = null;

                mapStringCondition.ConditionList.Add(condition);
            }
            else
            {
                // 通过英文逗号分隔要同时满足的条件
                string[] ifConditionStringList = ifConditionString.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                for (int j = 0; j < ifConditionStringList.Length; j++)
                {
                    Condition condition = new Condition();

                    string        oneKeyValuePairString = ifConditionStringList[j].Trim();
                    string        fieldName             = null;
                    StringBuilder fieldNameBuilder      = new StringBuilder();
                    int           charIndex             = 0;
                    bool          isFoundSignOfRelation = false;
                    for (charIndex = 0; charIndex < oneKeyValuePairString.Length; ++charIndex)
                    {
                        char c = oneKeyValuePairString[charIndex];
                        if (c == '=' || c == '>' || c == '<')
                        {
                            fieldName             = fieldNameBuilder.ToString().Trim();
                            isFoundSignOfRelation = true;
                            break;
                        }
                        else
                        {
                            fieldNameBuilder.Append(c);
                        }
                    }
                    if (string.IsNullOrEmpty(fieldName))
                    {
                        errorString = string.Format("mapString型的内容检查规则声明错误,if后的括号中({0})未声明字段名,请按字段名、关系符、取值的形式进行声明,如type>1\n", oneKeyValuePairString);
                        return(false);
                    }
                    else if (isFoundSignOfRelation == false)
                    {
                        errorString = string.Format("mapString型的内容检查规则声明错误,if后的括号中({0})未声明关系符,请按字段名、关系符、取值的形式进行声明,如type>1\n", oneKeyValuePairString);
                        return(false);
                    }
                    // 检查字段是否存在
                    FieldInfo targetFieldInfo = TableCheckHelper.GetFieldByIndexDefineString(fieldName, AppValues.TableInfo[fieldInfo.TableName], out errorString);
                    if (errorString != null)
                    {
                        errorString = string.Format("mapString型的内容检查规则声明错误,无法根据索引字符串\"{0}\"在表格{1}找到要对应的字段,错误信息为:{2}\n", fieldName, fieldInfo.TableName, errorString);
                        return(false);
                    }
                    // 检查字段类型是否符合要求
                    if (targetFieldInfo.DataType != DataType.Int && targetFieldInfo.DataType != DataType.Long && targetFieldInfo.DataType != DataType.Float && targetFieldInfo.DataType != DataType.Bool && targetFieldInfo.DataType != DataType.String)
                    {
                        errorString = string.Format("mapString型的内容检查规则声明错误,条件字段({0})的数据类型为{1},而mapString型内容检查规则中,if条件字段只能为int、long、float、bool或string型\n", fieldName, targetFieldInfo.DataType);
                        return(false);
                    }
                    condition.FieldInfo = targetFieldInfo;

                    // 解析填写的关系符
                    string        signOfRelation        = null;
                    StringBuilder signOfRelationBuilder = new StringBuilder();
                    if (charIndex == oneKeyValuePairString.Length)
                    {
                        errorString = string.Format("mapString型的内容检查规则声明错误,if后的括号中({0})未声明取值,请按字段名、关系符、取值的形式进行声明,如type>1\n", oneKeyValuePairString);
                        return(false);
                    }
                    for (; charIndex < oneKeyValuePairString.Length; ++charIndex)
                    {
                        char c = oneKeyValuePairString[charIndex];
                        if (c == '=' || c == '>' || c == '<')
                        {
                            signOfRelationBuilder.Append(c);
                        }
                        else
                        {
                            break;
                        }
                    }
                    signOfRelation = signOfRelationBuilder.ToString();
                    if (signOfRelation == "=")
                    {
                        condition.Relation = Relation.Equal;
                    }
                    else if (signOfRelation == ">")
                    {
                        condition.Relation = Relation.GreaterThan;
                    }
                    else if (signOfRelation == ">=")
                    {
                        condition.Relation = Relation.GreaterThanOrEqual;
                    }
                    else if (signOfRelation == "<")
                    {
                        condition.Relation = Relation.LessThan;
                    }
                    else if (signOfRelation == "<=")
                    {
                        condition.Relation = Relation.LessThanOrEqual;
                    }
                    else
                    {
                        errorString = string.Format("mapString型的内容检查规则声明错误,关系符非法,只支持=、>、>=、<、<=,你填写的为{0}\n", oneKeyValuePairString);
                        return(false);
                    }
                    // bool、string型只有关系符=
                    if (condition.Relation != Relation.Equal && (targetFieldInfo.DataType == DataType.Bool || targetFieldInfo.DataType == DataType.String))
                    {
                        errorString = string.Format("mapString型的内容检查规则声明错误,条件字段({0})为{1}类型,只能进行等于判定,而你设置的关系符为{2}\n", fieldName, targetFieldInfo.DataType, condition.Relation);
                        return(false);
                    }

                    // 解析填写的取值
                    string valueString = oneKeyValuePairString.Substring(charIndex).Trim();
                    if (targetFieldInfo.DataType == DataType.Int)
                    {
                        int value = 0;
                        if (int.TryParse(valueString, out value) == false)
                        {
                            errorString = string.Format("mapString型的内容检查规则声明错误,条件字段({0})对应int型的取值({1})非法\n", fieldName, valueString);
                            return(false);
                        }
                        else
                        {
                            condition.Value = value;
                        }
                    }
                    else if (targetFieldInfo.DataType == DataType.Long)
                    {
                        long value = 0;
                        if (long.TryParse(valueString, out value) == false)
                        {
                            errorString = string.Format("mapString型的内容检查规则声明错误,条件字段({0})对应long型的取值({1})非法\n", fieldName, valueString);
                            return(false);
                        }
                        else
                        {
                            condition.Value = value;
                        }
                    }
                    else if (targetFieldInfo.DataType == DataType.Float)
                    {
                        double value = 0;
                        if (double.TryParse(valueString, out value) == false)
                        {
                            errorString = string.Format("mapString型的内容检查规则声明错误,条件字段({0})对应float型的取值({1})非法\n", fieldName, valueString);
                            return(false);
                        }
                        else
                        {
                            condition.Value = value;
                        }
                    }
                    else if (targetFieldInfo.DataType == DataType.Bool)
                    {
                        if ("1".Equals(valueString) || "true".Equals(valueString, StringComparison.CurrentCultureIgnoreCase))
                        {
                            condition.Value = true;
                        }
                        else if ("0".Equals(valueString) || "false".Equals(valueString, StringComparison.CurrentCultureIgnoreCase))
                        {
                            condition.Value = true;
                        }
                        else
                        {
                            errorString = string.Format("mapString型的内容检查规则声明错误,条件字段({0})对应bool型的取值({1})非法,bool型的值应用数字1、0或true、false进行声明\n", fieldName, valueString);
                            return(false);
                        }
                    }
                    else if (targetFieldInfo.DataType == DataType.String)
                    {
                        condition.Value = valueString;
                    }
                    else
                    {
                        errorString = "用CheckMapString函数处理非法的mapString型检查规则中定义的条件字段类型";
                        AppLog.LogErrorAndExit(errorString);
                        return(false);
                    }

                    mapStringCondition.ConditionList.Add(condition);
                }
            }

            // mapString型下属字段要求解析
            string mapStringRequiredString = tempCheckRule.Substring(rightBracket + 1).Trim();
            if (!mapStringRequiredString.StartsWith("[") || !mapStringRequiredString.EndsWith("]"))
            {
                errorString = string.Format("mapString型的内容检查规则声明错误,每条检查规则中的字段要求声明必须在if条件声明后,在方括号内声明,你填写的为{0}\n", mapStringRequiredString);
                return(false);
            }
            mapStringRequiredString = mapStringRequiredString.Substring(1, mapStringRequiredString.Length - 2).Trim();
            MapStringRequiredInfo mapStringRequiredInfo = _GetMapStringRequiredInfo(mapStringRequiredString, fieldInfo, out errorString);
            if (errorString != null)
            {
                errorString = string.Format("mapString型的内容检查规则声明错误,输入的字段要求错误,你填写的为\"{0}\",错误原因为:{1}\n", mapStringRequiredString, errorString);
                return(false);
            }
            else
            {
                mapStringCheckRule.CheckRuleList.Add(mapStringCondition, mapStringRequiredInfo);
            }
        }

        // 按解析出的检查规则对mapString型进行检查
        StringBuilder errorStringBuilder = new StringBuilder();
        int           ruleIndex          = 0;

        foreach (var item in mapStringCheckRule.CheckRuleList)
        {
            MapStringCondition    condition    = item.Key;
            MapStringRequiredInfo requiredInfo = item.Value;
            StringBuilder         oneConditionStringBuilder = new StringBuilder();

            // 先找出其他列满足检查条件的行
            // 记录符合检查条件的数据索引值(从0计),这里先将所有数据行加入,然后逐步排除不满足条件的数据行
            List <int> targetDataIndex = new List <int>();
            int        dataCount       = fieldInfo.Data.Count;
            for (int i = 0; i < dataCount; ++i)
            {
                targetDataIndex.Add(i);
            }

            List <int> emptyConditionRowIndex = new List <int>();
            for (int conditionIndex = 0; conditionIndex < condition.ConditionList.Count; ++conditionIndex)
            {
                Condition oneCondition = condition.ConditionList[conditionIndex];
                // 排除标为all的条件
                if (oneCondition.FieldInfo != null)
                {
                    List <int> tempEmptyConditionRowIndex = null;
                    _GetTargetDataIndex(oneCondition, targetDataIndex, oneCondition.FieldInfo, out tempEmptyConditionRowIndex);
                    if (tempEmptyConditionRowIndex != null && tempEmptyConditionRowIndex.Count > 0)
                    {
                        foreach (int rowIndex in tempEmptyConditionRowIndex)
                        {
                            if (!emptyConditionRowIndex.Contains(rowIndex))
                            {
                                emptyConditionRowIndex.Add(rowIndex);
                            }
                        }
                    }
                }
            }
            if (emptyConditionRowIndex.Count > 0)
            {
                string warningString = string.Format("警告:mapString型字段\"{0}\"(列号:{1})的检查条件({2})中的字段,因为以下行中数据无效,视为不满足条件,不对对应行中的mapString进行检查:{3}\n", fieldInfo.FieldName, ExcelMethods.GetExcelColumnName(fieldInfo.ColumnSeq + 1), checkRuleList[ruleIndex], Utils.CombineString(emptyConditionRowIndex, ","));
                AppLog.LogWarning(warningString);
            }

            // 对满足检查条件的数据行进行mapString内容检查
            List <int> emptyDataRowIndex = new List <int>();
            foreach (int index in targetDataIndex)
            {
                // 若为空值,跳过检查,但进行警告
                if (fieldInfo.Data[index] == null)
                {
                    emptyDataRowIndex.Add(index + ExcelTableSetting.DataFieldDataStartRowIndex + 1);
                    continue;
                }

                JsonData jsonData = fieldInfo.Data[index] as JsonData;
                if (_CheckMapStringData(jsonData, requiredInfo, out errorString) == false)
                {
                    oneConditionStringBuilder.AppendFormat("第{0}行填写的数据({1}):\n{2}\n", index + ExcelTableSetting.DataFieldDataStartRowIndex + 1, fieldInfo.JsonString[index], errorString);
                }
            }
            string oneConditionString = oneConditionStringBuilder.ToString();
            if (!string.IsNullOrEmpty(oneConditionString))
            {
                errorStringBuilder.AppendFormat("以下行数据未通过检查规则\"{0}\":\n{1}", checkRuleList[ruleIndex], oneConditionString);
            }

            if (emptyDataRowIndex.Count > 0)
            {
                string warningString = string.Format("警告:在对mapString型字段\"{0}\"(列号:{1})执行检查条件({2})时,因为以下行中数据无效,跳过对mapString的检查:{3}\n", fieldInfo.FieldName, ExcelMethods.GetExcelColumnName(fieldInfo.ColumnSeq + 1), checkRuleList[ruleIndex], Utils.CombineString(emptyDataRowIndex, ","));
                AppLog.LogWarning(warningString);
            }

            ++ruleIndex;
        }

        errorString = errorStringBuilder.ToString();
        if (string.IsNullOrEmpty(errorString))
        {
            errorString = null;
            return(true);
        }
        else
        {
            return(false);
        }
    }