event/reflect.go

202 lines
5.2 KiB
Go
Raw Normal View History

// Package event ...
//
// Description : event ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2023-02-01 14:30
package event
import (
"reflect"
"strings"
"sync"
)
var (
// ReflectTypeInstance 反射实例
ReflectTypeInstance *ReflectType
)
func init() {
ReflectTypeInstance = &ReflectType{
lock: &sync.RWMutex{},
cacheTable: make(map[string]*StructInfo),
}
}
// ReflectType 反射数据类型
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:31 2023/2/1
type ReflectType struct {
// 数据锁
lock *sync.RWMutex
// 反射结果缓存
cacheTable map[string]*StructInfo
}
// Do 反射获取数据类型
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:34 2023/2/1
//
// 为特定结构体生成全局唯一的标识, 并进行缓存, 加速反射结果获取
func (rt *ReflectType) Do(dataFlag string, data interface{}) *StructInfo {
rt.lock.Lock()
defer rt.lock.Unlock()
if cacheResult, exist := rt.cacheTable[dataFlag]; exist {
// 缓存存在, 直接是有缓存结果
return cacheResult
}
// 缓存不存在, 解析
res := &StructInfo{
Flag: dataFlag,
IsStruct: false,
StructFieldList: make([]*StructField, 0),
}
reflectType := reflect.TypeOf(data)
if reflectType.Kind() == reflect.Ptr {
reflectType = reflectType.Elem()
}
if reflectType.Kind() != reflect.Struct {
// 非结构体,无需反射
return res
}
res.IsStruct = true
for idx := 0; idx < reflectType.NumField(); idx++ {
field := &StructField{
Idx: idx,
Name: reflectType.Field(idx).Name,
Type: reflectType.Field(idx).Type.Kind(),
JsonTag: reflectType.Field(idx).Tag.Get(JsonTag),
EventTag: reflectType.Field(idx).Tag.Get(OutEventTag),
MappingRule: nil,
}
res.StructFieldList = append(res.StructFieldList, field)
}
return res
}
// fillTagInfo 填充标签信息
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:11 2023/2/1
func (rt *ReflectType) fillTagInfo(field *StructField) {
if len(field.JsonTag) == 0 {
field.JsonTag = field.Name
}
// jsonTag 去掉 omitempty
jsonTagValArr := strings.Split(field.JsonTag, ",")
for _, item := range jsonTagValArr {
if len(item) > 0 && item != OmitemptyTag {
field.JsonTag = item
break
}
}
// 没有设置event tag,则和
if len(field.EventTag) == 0 {
field.EventTag = field.JsonTag
}
}
// fillMappingRule 解析参数映射规则
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:14 2023/2/1
//
// mapping:"user_id:param#user_id|header#id"
func (rt *ReflectType) fillMappingRule(field *StructField, inputMappingVal string, inputPriorityVal string) {
rule := &MappingRule{
RuleList: make([]MappingRuleItem, 0),
Priority: "",
TargetField: "",
}
switch inputPriorityVal {
case PriorityLocation:
rule.Priority = PriorityLocation
case PriorityField:
rule.Priority = PriorityField
default:
rule.Priority = PriorityField
}
if len(inputMappingVal) == 0 {
// 没有指定规则, 有默认规则
for _, location := range mappingLocationList {
rule.RuleList = append(rule.RuleList, MappingRuleItem{
Location: location,
Field: field.JsonTag,
})
}
field.MappingRule = rule
return
}
mappingArr := strings.Split(inputMappingVal, ",")
for _, item := range mappingArr {
item = strings.TrimSpace(item)
// 要赋值的字段名
itemArr := strings.Split(item, ":")
2023-02-01 20:15:15 +08:00
if len(itemArr) != 2 {
// 配置格式错误, 跳过
continue
}
rule.TargetField = strings.TrimSpace(itemArr[0])
2023-02-01 20:15:15 +08:00
mapRuleArr := strings.Split(strings.TrimSpace(itemArr[1]), "|")
for _, itemMapRule := range mapRuleArr {
itemMapRule = strings.TrimLeft(itemMapRule, "#")
itemMapRuleArr := strings.Split(itemMapRule, "#")
// 注意 : # 为特殊分隔符, 如配置成 mapping:"project_id:#source_project_id#xxx_project_id" 实际等价于 mapping:"project_id:#source_project_id" 多余配置自动跳过
if len(itemMapRuleArr[0]) < 2 {
// 没有指定位置默认all, 即配置格式: mapping:"project_id:#source_project_id"
itemMapRuleArr[0] = MappingLocationAll
itemMapRuleArr = []string{MappingLocationAll, itemMapRuleArr[0]}
}
switch itemMapRuleArr[0] {
// 从header读取
case MappingLocationHeader:
rule.RuleList = append(rule.RuleList, MappingRuleItem{
Location: MappingLocationHeader,
Field: itemMapRuleArr[1],
})
// 从请求参数读取
case MappingLocationParam:
rule.RuleList = append(rule.RuleList, MappingRuleItem{
Location: MappingLocationParam,
Field: itemMapRuleArr[1],
})
// 从响应数据读取
case MappingLocationResponse:
rule.RuleList = append(rule.RuleList, MappingRuleItem{
Location: MappingLocationResponse,
Field: itemMapRuleArr[1],
})
// 从扩展数据读取
case MappingLocationExtension:
rule.RuleList = append(rule.RuleList, MappingRuleItem{
Location: MappingLocationExtension,
Field: itemMapRuleArr[1],
})
// 全部读取一遍
case MappingLocationAll:
fallthrough
default:
for _, itemLocation := range mappingLocationList {
rule.RuleList = append(rule.RuleList, MappingRuleItem{
Location: itemLocation,
Field: itemMapRuleArr[1],
})
}
}
}
}
}