Files
apinto/plugin/plugins.go
2022-08-24 16:42:39 +08:00

98 lines
2.6 KiB
Go

package plugin
import (
"fmt"
"github.com/eolinker/eosc"
"github.com/eolinker/eosc/common/bean"
"github.com/eolinker/eosc/variable"
"reflect"
"sync"
)
var (
pluginManger IPluginManager
ones sync.Once
)
type Plugins map[string]*Config
func (p Plugins) Reset(originVal reflect.Value, targetVal reflect.Value, variables eosc.IVariable) ([]string, error) {
ones.Do(func() {
bean.Autowired(&pluginManger)
})
if originVal.Kind() != reflect.Map {
return nil, fmt.Errorf("plugin map reset error:%w %s", variable.ErrorUnsupportedKind, originVal.Kind())
}
targetType := targetVal.Type()
newMap := reflect.MakeMap(targetType)
usedVariables := make([]string, 0, variables.Len())
for _, key := range originVal.MapKeys() {
// 判断是否存在对应的插件配
cfgType, ok := pluginManger.GetConfigType(key.String())
if !ok {
return nil, fmt.Errorf("plugin %s not found", key.String())
}
value := originVal.MapIndex(key)
newValue := reflect.New(targetType.Elem())
used, err := pluginConfigSet(value, newValue, variables, cfgType)
if err != nil {
return nil, err
}
usedVariables = append(usedVariables, used...)
newMap.SetMapIndex(key, newValue.Elem())
}
targetVal.Set(newMap)
return usedVariables, nil
}
func pluginConfigSet(originVal reflect.Value, targetVal reflect.Value, variables eosc.IVariable, cfgType reflect.Type) ([]string, error) {
if targetVal.Kind() == reflect.Ptr {
if !targetVal.Elem().IsValid() {
targetType := targetVal.Type()
newVal := reflect.New(targetType.Elem())
targetVal.Set(newVal)
}
targetVal = targetVal.Elem()
}
usedVariables := make([]string, 0, variables.Len())
switch targetVal.Kind() {
case reflect.Struct:
{
targetType := targetVal.Type()
for i := 0; i < targetType.NumField(); i++ {
field := targetType.Field(i)
var fieldValue reflect.Value
switch field.Type.Kind() {
case reflect.Interface:
if cfgType.Kind() == reflect.Ptr {
cfgType = cfgType.Elem()
}
fieldValue = reflect.New(cfgType)
default:
fieldValue = reflect.New(field.Type)
}
var value reflect.Value
switch originVal.Elem().Kind() {
case reflect.Map:
{
tag := field.Tag.Get("json")
value = originVal.Elem().MapIndex(reflect.ValueOf(tag))
}
default:
value = originVal.Elem()
}
variables, err := variable.RecurseReflect(value, fieldValue, variables)
if err != nil {
return nil, err
}
usedVariables = append(usedVariables, variables...)
targetVal.Field(i).Set(fieldValue.Elem())
}
}
case reflect.Ptr:
return pluginConfigSet(originVal, targetVal, variables, cfgType)
}
return usedVariables, nil
}