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]any, path []string) map[string]any {
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]any)
25 m[k] = m3
26 m = m3
27 continue
28 }
29 m3, ok := m2.(map[string]any)
30 if !ok {
31 // intermediate key is a value
32 // => replace with a new map
33 m3 = make(map[string]any)
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 the main package.
44 // TODO: move it to a common place.
45 func flattenAndMergeMap(shadow, m map[string]any, prefix, delimiter string) map[string]any {
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]any)
52 }
53 54 var m2 map[string]any
55 if prefix != "" {
56 prefix += delimiter
57 }
58 for k, val := range m {
59 fullKey := prefix + k
60 switch val := val.(type) {
61 case map[string]any:
62 m2 = val
63 case map[any]any:
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 }
75