github.com/turingchain2020/turingchain@v1.1.21/types/reflect.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package types 6 7 import ( 8 "encoding/json" 9 "errors" 10 "fmt" 11 "reflect" 12 "strings" 13 "sync" 14 "unicode" 15 "unicode/utf8" 16 17 proto "github.com/golang/protobuf/proto" 18 ) 19 20 //QueryFunc support query 21 var QueryFunc = NewQueryData("Query_") 22 23 func buildFuncList(funclist []interface{}) map[string]bool { 24 list := make(map[string]bool) 25 for i := 0; i < len(funclist); i++ { 26 tyname := reflect.TypeOf(funclist[i]).Elem().Name() 27 datas := strings.Split(tyname, "_") 28 if len(datas) != 2 { 29 continue 30 } 31 list["Get"+datas[1]] = true 32 } 33 return list 34 } 35 36 // Is this an exported - upper case - name? 37 func isExported(name string) bool { 38 rune, _ := utf8.DecodeRuneInString(name) 39 return unicode.IsUpper(rune) 40 } 41 42 // ListActionMethod list action的所有的方法 43 func ListActionMethod(action interface{}, funclist []interface{}) map[string]reflect.Method { 44 typ := reflect.TypeOf(action) 45 flist := buildFuncList(funclist) 46 methods := make(map[string]reflect.Method) 47 for m := 0; m < typ.NumMethod(); m++ { 48 method := typ.Method(m) 49 //mtype := method.Type 50 mname := method.Name 51 // Method must be exported. 52 if method.PkgPath != "" || !isExported(mname) { 53 continue 54 } 55 if mname == "GetValue" { 56 methods[mname] = method 57 continue 58 } 59 if flist[mname] { 60 methods[mname] = method 61 } 62 } 63 return methods 64 } 65 66 // ListType list type 67 func ListType(tys []interface{}) map[string]reflect.Type { 68 typelist := make(map[string]reflect.Type) 69 for _, ty := range tys { 70 typ := reflect.TypeOf(ty).Elem() 71 typelist[typ.Name()] = typ 72 } 73 return typelist 74 } 75 76 // ListMethod list Method 77 func ListMethod(action interface{}) map[string]reflect.Method { 78 typ := reflect.TypeOf(action) 79 return ListMethodByType(typ) 80 } 81 82 // ListMethodByType list Method 通过type类型 83 func ListMethodByType(typ reflect.Type) map[string]reflect.Method { 84 methods := make(map[string]reflect.Method) 85 for m := 0; m < typ.NumMethod(); m++ { 86 method := typ.Method(m) 87 //mtype := method.Type 88 mname := method.Name 89 // Method must be exported. 90 if method.PkgPath != "" || !isExported(mname) { 91 continue 92 } 93 methods[mname] = method 94 } 95 return methods 96 } 97 98 var nilValue = reflect.ValueOf(nil) 99 100 // GetActionValue 获取执行器的action value 101 func GetActionValue(action interface{}, funclist map[string]reflect.Method) (vname string, vty int32, v reflect.Value, err error) { 102 defer func() { 103 if e := recover(); e != nil { 104 vname = "" 105 vty = 0 106 v = nilValue 107 err = ErrDecode 108 } 109 }() 110 var ty int32 111 if a, ok := action.(execTypeGet); ok { 112 ty = a.GetTy() 113 } 114 value := reflect.ValueOf(action) 115 if _, ok := funclist["GetValue"]; !ok { 116 return "", 0, nilValue, ErrDecode 117 } 118 rcvr := funclist["GetValue"].Func.Call([]reflect.Value{value}) 119 elem := rcvr[0].Elem() 120 sname := elem.Type().String() 121 index := strings.LastIndex(sname, "_") 122 if index == -1 || index == (len(sname)-1) { 123 return "", 0, nilValue, ErrDecode 124 } 125 tyname := sname[index+1:] 126 funcname := "Get" + tyname 127 if _, ok := funclist[funcname]; !ok { 128 return "", 0, nilValue, ErrDecode 129 } 130 val := funclist[funcname].Func.Call([]reflect.Value{value}) 131 if len(val) == 0 || val[0].IsNil() { 132 return "", 0, nilValue, ErrDecode 133 } 134 return tyname, ty, val[0], nil 135 } 136 137 // IsOK 是否存在 138 func IsOK(list []reflect.Value, n int) bool { 139 if len(list) != n { 140 return false 141 } 142 for i := 0; i < len(list); i++ { 143 if !IsNil(list[i]) && !list[i].CanInterface() { 144 return false 145 } 146 } 147 return true 148 } 149 150 // CallQueryFunc 获取查询接口函数 151 func CallQueryFunc(this reflect.Value, f reflect.Method, in Message) (reply Message, err error) { 152 valueret := f.Func.Call([]reflect.Value{this, reflect.ValueOf(in)}) 153 if len(valueret) != 2 { 154 return nil, ErrMethodNotFound 155 } 156 if !valueret[0].CanInterface() { 157 return nil, ErrMethodNotFound 158 } 159 if !valueret[1].CanInterface() { 160 return nil, ErrMethodNotFound 161 } 162 r1 := valueret[0].Interface() 163 if r1 != nil { 164 if r, ok := r1.(Message); ok { 165 reply = r 166 } else { 167 return nil, ErrMethodReturnType 168 } 169 } 170 //参数2 171 r2 := valueret[1].Interface() 172 if r2 != nil { 173 if r, ok := r2.(error); ok { 174 err = r 175 } else { 176 return nil, ErrMethodReturnType 177 } 178 } 179 if reply == nil && err == nil { 180 return nil, ErrActionNotSupport 181 } 182 return reply, err 183 } 184 185 // BuildQueryType 构建查询方法 186 func BuildQueryType(prefix string, methods map[string]reflect.Method) (map[string]reflect.Method, map[string]reflect.Type) { 187 tys := make(map[string]reflect.Type) 188 ms := make(map[string]reflect.Method) 189 for name, method := range methods { 190 if !strings.HasPrefix(name, prefix) { 191 continue 192 } 193 ty := method.Type 194 if ty.NumIn() != 2 { 195 continue 196 } 197 paramIn := ty.In(1) 198 if paramIn.Kind() != reflect.Ptr { 199 continue 200 } 201 p := reflect.New(ty.In(1).Elem()) 202 queryin := p.Interface() 203 if _, ok := queryin.(proto.Message); !ok { 204 continue 205 } 206 if ty.NumOut() != 2 { 207 continue 208 } 209 if !ty.Out(0).AssignableTo(reflect.TypeOf((*proto.Message)(nil)).Elem()) { 210 continue 211 } 212 if !ty.Out(1).AssignableTo(reflect.TypeOf((*error)(nil)).Elem()) { 213 continue 214 } 215 name = name[len(prefix):] 216 tys[name] = ty 217 ms[name] = method 218 } 219 return ms, tys 220 } 221 222 // QueryData 查询结构体 223 type QueryData struct { 224 sync.RWMutex 225 prefix string 226 funcMap map[string]map[string]reflect.Method 227 typeMap map[string]map[string]reflect.Type 228 valueMap map[string]reflect.Value 229 } 230 231 // NewQueryData new一个新的QueryData 232 func NewQueryData(prefix string) *QueryData { 233 data := &QueryData{ 234 prefix: prefix, 235 funcMap: make(map[string]map[string]reflect.Method), 236 typeMap: make(map[string]map[string]reflect.Type), 237 valueMap: make(map[string]reflect.Value), 238 } 239 return data 240 } 241 242 // Register 注册 243 func (q *QueryData) Register(key string, obj interface{}) { 244 if _, existed := q.funcMap[key]; existed { 245 panic(fmt.Sprintf("QueryData Register dup for key=%s", key)) 246 } 247 q.funcMap[key], q.typeMap[key] = BuildQueryType(q.prefix, ListMethod(obj)) 248 249 } 250 251 // SetThis 设置 252 func (q *QueryData) SetThis(key string, this reflect.Value) { 253 q.Lock() 254 defer q.Unlock() 255 q.valueMap[key] = this 256 } 257 258 func (q *QueryData) getThis(key string) (reflect.Value, bool) { 259 q.RLock() 260 defer q.RUnlock() 261 v, ok := q.valueMap[key] 262 return v, ok 263 } 264 265 // GetFunc 获取函数 266 func (q *QueryData) GetFunc(driver, name string) (reflect.Method, error) { 267 funclist, ok := q.funcMap[driver] 268 if !ok { 269 return reflect.Method{}, ErrActionNotSupport 270 } 271 if f, ok := funclist[name]; ok { 272 return f, nil 273 } 274 return reflect.Method{}, ErrActionNotSupport 275 } 276 277 // GetType 获取类型 278 func (q *QueryData) GetType(driver, name string) (reflect.Type, error) { 279 typelist, ok := q.typeMap[driver] 280 if !ok { 281 return nil, ErrActionNotSupport 282 } 283 if t, ok := typelist[name]; ok { 284 return t, nil 285 } 286 return nil, ErrActionNotSupport 287 } 288 289 // Decode 编码 290 func (q *QueryData) Decode(driver, name string, in []byte) (reply Message, err error) { 291 ty, err := q.GetType(driver, name) 292 if err != nil { 293 return nil, err 294 } 295 p := reflect.New(ty.In(1).Elem()) 296 queryin := p.Interface() 297 if paramIn, ok := queryin.(proto.Message); ok { 298 err = Decode(in, paramIn) 299 return paramIn, err 300 } 301 return nil, ErrActionNotSupport 302 } 303 304 // DecodeJSON 编码成json格式 305 func (q *QueryData) DecodeJSON(driver, name string, in json.Marshaler) (reply Message, err error) { 306 ty, err := q.GetType(driver, name) 307 if err != nil { 308 return nil, err 309 } 310 p := reflect.New(ty.In(1).Elem()) 311 queryin := p.Interface() 312 if paramIn, ok := queryin.(proto.Message); ok { 313 data, err := in.MarshalJSON() 314 if err != nil { 315 return nil, err 316 } 317 err = JSONToPB(data, paramIn) 318 return paramIn, err 319 } 320 return nil, ErrActionNotSupport 321 } 322 323 // Call 查询函数回调 324 func (q *QueryData) Call(driver, name string, in Message) (reply Message, err error) { 325 defer func() { 326 if r := recover(); r != nil { 327 tlog.Error("query data call error", "driver", driver, "name", name, "param", in, "msg", r) 328 switch x := r.(type) { 329 case string: 330 err = errors.New(x) 331 case error: 332 err = x 333 default: 334 err = errors.New("Unknown panic") 335 } 336 reply = nil 337 } 338 }() 339 f, err := q.GetFunc(driver, name) 340 if err != nil { 341 return nil, err 342 } 343 m, ok := q.getThis(driver) 344 if !ok { 345 return nil, ErrQueryThistIsNotSet 346 } 347 return CallQueryFunc(m, f, in) 348 } 349 350 //IsNil 判断所有的空值 351 func IsNil(a interface{}) (ok bool) { 352 defer func() { 353 if e := recover(); e != nil { 354 ok = false 355 } 356 }() 357 if v, ok := a.(reflect.Value); ok { 358 if !v.IsValid() { 359 return true 360 } 361 return v.IsNil() 362 } 363 return a == nil || reflect.ValueOf(a).IsNil() 364 } 365 366 //IsNilP 空指针或者接口 367 func IsNilP(a interface{}) bool { 368 if a == nil { 369 return true 370 } 371 var v reflect.Value 372 if val, ok := a.(reflect.Value); ok { 373 v = val 374 } else { 375 v = reflect.ValueOf(a) 376 } 377 if !v.IsValid() { 378 return true 379 } 380 if v.Kind() == reflect.Interface || v.Kind() == reflect.Ptr { 381 return v.IsNil() 382 } 383 return false 384 }