|
1 package javaproperties |
|
2 |
|
3 import ( |
|
4 "strings" |
|
5 |
|
6 "github.com/spf13/cast" |
|
7 ) |
|
8 |
|
9 // THIS CODE IS COPIED HERE: IT SHOULD NOT BE MODIFIED |
|
10 // AT SOME POINT IT WILL BE MOVED TO A COMMON PLACE |
|
11 // deepSearch scans deep maps, following the key indexes listed in the |
|
12 // sequence "path". |
|
13 // The last value is expected to be another map, and is returned. |
|
14 // |
|
15 // In case intermediate keys do not exist, or map to a non-map value, |
|
16 // a new map is created and inserted, and the search continues from there: |
|
17 // the initial map "m" may be modified! |
|
18 func deepSearch(m map[string]interface{}, path []string) map[string]interface{} { |
|
19 for _, k := range path { |
|
20 m2, ok := m[k] |
|
21 if !ok { |
|
22 // intermediate key does not exist |
|
23 // => create it and continue from there |
|
24 m3 := make(map[string]interface{}) |
|
25 m[k] = m3 |
|
26 m = m3 |
|
27 continue |
|
28 } |
|
29 m3, ok := m2.(map[string]interface{}) |
|
30 if !ok { |
|
31 // intermediate key is a value |
|
32 // => replace with a new map |
|
33 m3 = make(map[string]interface{}) |
|
34 m[k] = m3 |
|
35 } |
|
36 // continue search from here |
|
37 m = m3 |
|
38 } |
|
39 return m |
|
40 } |
|
41 |
|
42 // flattenAndMergeMap recursively flattens the given map into a new map |
|
43 // Code is based on the function with the same name in tha main package. |
|
44 // TODO: move it to a common place |
|
45 func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} { |
|
46 if shadow != nil && prefix != "" && shadow[prefix] != nil { |
|
47 // prefix is shadowed => nothing more to flatten |
|
48 return shadow |
|
49 } |
|
50 if shadow == nil { |
|
51 shadow = make(map[string]interface{}) |
|
52 } |
|
53 |
|
54 var m2 map[string]interface{} |
|
55 if prefix != "" { |
|
56 prefix += delimiter |
|
57 } |
|
58 for k, val := range m { |
|
59 fullKey := prefix + k |
|
60 switch val.(type) { |
|
61 case map[string]interface{}: |
|
62 m2 = val.(map[string]interface{}) |
|
63 case map[interface{}]interface{}: |
|
64 m2 = cast.ToStringMap(val) |
|
65 default: |
|
66 // immediate value |
|
67 shadow[strings.ToLower(fullKey)] = val |
|
68 continue |
|
69 } |
|
70 // recursively merge to shadow map |
|
71 shadow = flattenAndMergeMap(shadow, m2, fullKey, delimiter) |
|
72 } |
|
73 return shadow |
|
74 } |