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  }