github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/unstructured/xml_config.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package unstructured 21 22 import ( 23 "strings" 24 25 mxjv2 "github.com/clbanning/mxj/v2" 26 "github.com/spf13/cast" 27 28 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 29 ) 30 31 type xmlConfig struct { 32 name string 33 data mxjv2.Map 34 } 35 36 func init() { 37 // disable cast to float 38 mxjv2.CastValuesToFloat(false) 39 // enable cast to bool 40 mxjv2.CastValuesToBool(true) 41 // enable cast to int 42 mxjv2.CastValuesToInt(true) 43 44 CfgObjectRegistry().RegisterConfigCreator(appsv1alpha1.XML, func(name string) ConfigObject { 45 return &xmlConfig{name: name} 46 }) 47 } 48 49 func (x *xmlConfig) Update(key string, value any) error { 50 return x.data.SetValueForPath(value, key) 51 } 52 53 func (x *xmlConfig) RemoveKey(key string) error { 54 _ = x.data.Remove(key) 55 return nil 56 } 57 58 func (x *xmlConfig) Get(key string) interface{} { 59 keys := strings.Split(key, ".") 60 keysLen := len(keys) 61 m := prefixKeys(x.data.Old(), keys[:keysLen-1]) 62 if m != nil { 63 return m[keys[keysLen-1]] 64 } 65 return nil 66 } 67 68 func prefixKeys(m map[string]interface{}, keys []string) map[string]interface{} { 69 r := m 70 for _, k := range keys { 71 if m == nil { 72 break 73 } 74 v, ok := r[k] 75 if !ok { 76 return nil 77 } 78 79 switch vt := v.(type) { 80 default: 81 r = nil 82 case map[string]interface{}: 83 r = vt 84 } 85 } 86 return r 87 } 88 89 func (x *xmlConfig) GetString(key string) (string, error) { 90 v := x.Get(key) 91 if v != nil { 92 return cast.ToStringE(v) 93 } 94 return "", nil 95 } 96 97 func (x *xmlConfig) GetAllParameters() map[string]interface{} { 98 return x.data 99 } 100 101 func (x *xmlConfig) SubConfig(key string) ConfigObject { 102 v := x.Get(key) 103 if v == nil { 104 return nil 105 } 106 107 switch t := v.(type) { 108 case map[string]interface{}: 109 return &xmlConfig{data: t} 110 default: 111 return nil 112 } 113 } 114 115 func (x *xmlConfig) Marshal() (string, error) { 116 b, err := x.data.Xml() 117 if err != nil { 118 return "", err 119 } 120 return string(b), nil 121 } 122 123 func (x *xmlConfig) Unmarshal(str string) error { 124 m, err := mxjv2.NewMapXml([]byte(str), true) 125 if err != nil { 126 return err 127 } 128 x.data = m 129 return nil 130 }