dubbo.apache.org/dubbo-go/v3@v3.1.1/config/parsers/properties/properties.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package properties 19 20 import ( 21 "strings" 22 ) 23 24 import ( 25 "github.com/magiconair/properties" 26 ) 27 28 type Properties struct{} 29 30 func Parser() *Properties { 31 return &Properties{} 32 } 33 34 // Unmarshal parses the given properties bytes. 35 func (p *Properties) Unmarshal(b []byte) (map[string]interface{}, error) { 36 out := make(map[string]interface{}) 37 if load, err := properties.Load(b, properties.UTF8); err != nil { 38 return nil, err 39 } else { 40 // see viper#unmarshalReader 41 for _, key := range load.Keys() { 42 value, _ := load.Get(key) 43 // recursively build nested maps 44 path := strings.Split(key, ".") 45 lastKey := path[len(path)-1] 46 deepestMap := deepSearch(out, path[0:len(path)-1]) 47 // set innermost value 48 deepestMap[lastKey] = value 49 } 50 return out, nil 51 } 52 } 53 54 // Marshal marshals the given config map to YAML bytes. 55 func (p *Properties) Marshal(o map[string]interface{}) ([]byte, error) { 56 return nil, nil 57 } 58 59 // deepSearch scans deep maps, following the key indexes listed in the 60 // sequence "path". 61 // The last value is expected to be another map, and is returned. 62 // 63 // In case intermediate keys do not exist, or map to a non-map value, 64 // a new map is created and inserted, and the search continues from there: 65 // the initial map "m" may be modified! 66 func deepSearch(m map[string]interface{}, path []string) map[string]interface{} { 67 for _, k := range path { 68 m2, ok := m[k] 69 if !ok { 70 // intermediate key does not exist 71 // => create it and continue from there 72 m3 := make(map[string]interface{}) 73 m[k] = m3 74 m = m3 75 continue 76 } 77 m3, ok := m2.(map[string]interface{}) 78 if !ok { 79 // intermediate key is a value 80 // => replace with a new map 81 m3 = make(map[string]interface{}) 82 m[k] = m3 83 } 84 // continue search from here 85 m = m3 86 } 87 return m 88 }