github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/validate/matcher/blackWhiteMatch.go (about) 1 package matcher 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/antonmedv/expr/compiler" 8 "github.com/antonmedv/expr/parser" 9 "github.com/isyscore/isc-gobase/logger" 10 ) 11 12 type BlackWhiteMatch struct { 13 BlackMsg string 14 WhiteMsg string 15 } 16 17 func (blackWhiteMatch *BlackWhiteMatch) SetBlackMsg(format string, a ...any) { 18 blackWhiteMatch.BlackMsg = fmt.Sprintf(format, a...) 19 } 20 21 func (blackWhiteMatch *BlackWhiteMatch) SetWhiteMsg(format string, a ...any) { 22 blackWhiteMatch.WhiteMsg = fmt.Sprintf(format, a...) 23 } 24 25 func (blackWhiteMatch *BlackWhiteMatch) GetWhitMsg() string { 26 return blackWhiteMatch.WhiteMsg 27 } 28 29 func (blackWhiteMatch *BlackWhiteMatch) GetBlackMsg() string { 30 return blackWhiteMatch.BlackMsg 31 } 32 33 func addMatcher(objectTypeFullName string, objectFieldName string, matcher Matcher, errMsg string, accept bool) { 34 fieldMatcherMap, c1 := MatchMap[objectTypeFullName] 35 36 if !c1 { 37 fieldMap := make(map[string]*FieldMatcher) 38 var matchers []*Matcher 39 if matcher != nil { 40 matchers = append(matchers, &matcher) 41 } 42 43 if errMsg != "" { 44 errMsgData := errMsgChange(errMsg) 45 tree, err := parser.Parse(errMsgData) 46 if err != nil { 47 logger.Error("errMsg[%v] parse error: %v", errMsg, err.Error()) 48 return 49 } 50 51 program, err := compiler.Compile(tree, nil) 52 if err != nil { 53 logger.Error("errMsg[%v] compile error: %v", errMsg, err.Error()) 54 return 55 } 56 57 fieldMap[objectFieldName] = &FieldMatcher{FieldName: objectFieldName, ErrMsgProgram: program, Matchers: matchers, Accept: accept} 58 } else { 59 fieldMap[objectFieldName] = &FieldMatcher{FieldName: objectFieldName, Matchers: matchers, Accept: accept} 60 } 61 62 MatchMap[objectTypeFullName] = fieldMap 63 } else { 64 fieldMatcher, c2 := fieldMatcherMap[objectFieldName] 65 if !c2 { 66 var matchers []*Matcher 67 if matcher != nil { 68 matchers = append(matchers, &matcher) 69 } 70 71 if errMsg != "" { 72 tree, err := parser.Parse(errMsgChange(errMsg)) 73 if err != nil { 74 logger.Error("errMsg[%v] parse error: %v", errMsg, err.Error()) 75 return 76 } 77 78 program, err := compiler.Compile(tree, nil) 79 if err != nil { 80 logger.Error("errMsg[%v] compile error: %v", errMsg, err.Error()) 81 return 82 } 83 84 fieldMatcherMap[objectFieldName] = &FieldMatcher{FieldName: objectFieldName, ErrMsgProgram: program, Matchers: matchers, Accept: accept} 85 } else { 86 fieldMatcherMap[objectFieldName] = &FieldMatcher{FieldName: objectFieldName, Matchers: matchers, Accept: accept} 87 } 88 } else { 89 if matcher != nil { 90 fieldMatcher.Matchers = append(fieldMatcher.Matchers, &matcher) 91 } 92 fieldMatcher.Accept = accept 93 } 94 } 95 } 96 97 // 将#root和#current转换为root和#current,相当于移除井号 98 func rmvWell(expression string) string { 99 if strings.Contains(expression, "#root.") { 100 expression = strings.ReplaceAll(expression, "#root.", "root.") 101 } 102 103 if strings.Contains(expression, "#current") { 104 expression = strings.ReplaceAll(expression, "#current", "current") 105 } 106 return expression 107 } 108 109 var currentKey = "#current" 110 var rootKey = "#root" 111 112 func errMsgChange(errMsg string) string { 113 var matchKeys []string 114 var chgMsg strings.Builder 115 chgMsg.WriteString("sprintf(\"") 116 117 var b strings.Builder 118 b.Grow(len(errMsg)) 119 120 matchIndex := 0 121 matchLength := 0 122 for infoIndex, data := range errMsg { 123 c := string(data) 124 if c == "#" { 125 if findCurrentKey(infoIndex, 0, errMsg) { 126 matchIndex = 0 127 matchLength = len(currentKey) 128 b.WriteString("%v") 129 matchKeys = append(matchKeys, "current") 130 continue 131 } else if find, size, wordKey := findRootKey(infoIndex, 0, errMsg); find { 132 matchIndex = 0 133 matchLength = size 134 b.WriteString("%v") 135 matchKeys = append(matchKeys, "root"+wordKey) 136 continue 137 } 138 } else if matchIndex+1 < matchLength { 139 matchIndex++ 140 continue 141 } else { 142 b.WriteString(c) 143 } 144 } 145 146 chgMsg.WriteString(b.String()) 147 chgMsg.WriteString("\"") 148 149 matchKeysSize := len(matchKeys) 150 if matchKeysSize > 0 { 151 chgMsg.WriteString(", ") 152 } 153 154 for i, data := range matchKeys { 155 if i+1 < matchKeysSize { 156 chgMsg.WriteString(data) 157 chgMsg.WriteString(", ") 158 } else { 159 chgMsg.WriteString(data) 160 } 161 } 162 chgMsg.WriteString(")") 163 164 return chgMsg.String() 165 } 166 167 func findCurrentKey(infoIndex, matchIndex int, info string) bool { 168 if matchIndex >= len(currentKey) { 169 return true 170 } 171 if info[infoIndex:infoIndex+1] == currentKey[matchIndex:matchIndex+1] { 172 return findCurrentKey(infoIndex+1, matchIndex+1, info) 173 } 174 return false 175 } 176 177 func findRootKey(infoIndex, matchIndex int, info string) (bool, int, string) { 178 if matchIndex >= len(rootKey) { 179 nextKeyLength := nextMatchKeyLength(info[infoIndex:]) 180 if nextKeyLength > 0 { 181 return true, len(rootKey) + nextKeyLength, info[infoIndex : infoIndex+nextKeyLength] 182 } 183 return false, 0, "" 184 } 185 if info[infoIndex:infoIndex+1] == rootKey[matchIndex:matchIndex+1] { 186 return findRootKey(infoIndex+1, matchIndex+1, info) 187 } 188 return false, 0, "" 189 } 190 191 // 下一个英文的单词长度 192 // 97 ~ 122 193 // 65 ~ 90 194 func nextMatchKeyLength(errMsg string) int { 195 spaceIndex := strings.Index(strings.TrimSpace(errMsg), " ") 196 toMatchMsg := errMsg 197 if spaceIndex > 0 { 198 toMatchMsg = errMsg[:spaceIndex] 199 } 200 var index = 0 201 for _, c := range toMatchMsg { 202 // 判断是否是英文字符:a~z、A~Z和点号"." 203 if (c >= 97 && c <= 122) || (c >= 65 && c <= 90) || c == 46 { 204 index++ 205 continue 206 } else { 207 return index 208 } 209 } 210 return index 211 }