blob: 60fe15637548f191662fd43051627aa1b0bf5441 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package properties
import (
"strings"
)
import (
"github.com/magiconair/properties"
)
type Properties struct{}
func Parser() *Properties {
return &Properties{}
}
// Unmarshal parses the given properties bytes.
func (p *Properties) Unmarshal(b []byte) (map[string]interface{}, error) {
out := make(map[string]interface{})
if load, err := properties.Load(b, properties.UTF8); err != nil {
return nil, err
} else {
// see viper#unmarshalReader
for _, key := range load.Keys() {
value, _ := load.Get(key)
// recursively build nested maps
path := strings.Split(key, ".")
lastKey := path[len(path)-1]
deepestMap := deepSearch(out, path[0:len(path)-1])
// set innermost value
deepestMap[lastKey] = value
}
return out, nil
}
}
// Marshal marshals the given config map to YAML bytes.
func (p *Properties) Marshal(o map[string]interface{}) ([]byte, error) {
return nil, nil
}
// deepSearch scans deep maps, following the key indexes listed in the
// sequence "path".
// The last value is expected to be another map, and is returned.
//
// In case intermediate keys do not exist, or map to a non-map value,
// a new map is created and inserted, and the search continues from there:
// the initial map "m" may be modified!
func deepSearch(m map[string]interface{}, path []string) map[string]interface{} {
for _, k := range path {
m2, ok := m[k]
if !ok {
// intermediate key does not exist
// => create it and continue from there
m3 := make(map[string]interface{})
m[k] = m3
m = m3
continue
}
m3, ok := m2.(map[string]interface{})
if !ok {
// intermediate key is a value
// => replace with a new map
m3 = make(map[string]interface{})
m[k] = m3
}
// continue search from here
m = m3
}
return m
}