@@ -139,27 +139,23 @@ class NavigableMap implements Map<String, Object>, Cloneable {
139139 NavigableMap targetMap ,
140140 Map sourceMap ,
141141 boolean parseFlatKeys ) {
142-
143- Map collapseSourcedMap = collapseKeysWithSubscript(sourceMap)
144- if (! shouldSkipBlock(collapseSourcedMap, path)) {
145- for (Entry entry in collapseSourcedMap) {
146- Object sourceKeyObject = entry. key
147- Object sourceValue = entry. value
148- String sourceKey = String . valueOf(sourceKeyObject)
149- if (parseFlatKeys) {
150- String [] keyParts = sourceKey. split(/ \. / )
151- if (keyParts. length > 1 ) {
152- mergeMapEntry(rootMap, path, targetMap, sourceKey, sourceValue, parseFlatKeys)
153- def pathParts = keyParts[0 .. -2 ]
154- Map actualTarget = targetMap. navigateSubMap(pathParts as List , true )
155- sourceKey = keyParts[-1 ]
156- mergeMapEntry(rootMap, pathParts. join(' .' ), actualTarget, sourceKey, sourceValue, parseFlatKeys)
157- } else {
158- mergeMapEntry(rootMap, path, targetMap, sourceKey, sourceValue, parseFlatKeys)
159- }
142+ for (Entry entry in sourceMap) {
143+ Object sourceKeyObject = entry. key
144+ Object sourceValue = entry. value
145+ String sourceKey = String . valueOf(sourceKeyObject)
146+ if (parseFlatKeys) {
147+ String [] keyParts = sourceKey. split(/ \. / )
148+ if (keyParts. length > 1 ) {
149+ mergeMapEntry(rootMap, path, targetMap, sourceKey, sourceValue, parseFlatKeys)
150+ def pathParts = keyParts[0 .. -2 ]
151+ Map actualTarget = targetMap. navigateSubMap(pathParts as List , true )
152+ sourceKey = keyParts[-1 ]
153+ mergeMapEntry(rootMap, pathParts. join(' .' ), actualTarget, sourceKey, sourceValue, parseFlatKeys)
160154 } else {
161155 mergeMapEntry(rootMap, path, targetMap, sourceKey, sourceValue, parseFlatKeys)
162156 }
157+ } else {
158+ mergeMapEntry(rootMap, path, targetMap, sourceKey, sourceValue, parseFlatKeys)
163159 }
164160 }
165161 }
@@ -174,48 +170,97 @@ class NavigableMap implements Map<String, Object>, Cloneable {
174170 }
175171
176172 protected void mergeMapEntry (NavigableMap rootMap , String path , NavigableMap targetMap , String sourceKey , Object sourceValue , boolean parseFlatKeys , boolean isNestedSet = false ) {
177- Object currentValue = targetMap. containsKey(sourceKey) ? targetMap. get(sourceKey) : null
178- Object newValue
179- if (sourceValue instanceof Map ) {
180- List<String > newPathList = []
181- newPathList. addAll( targetMap. getPath() )
182- newPathList. add(sourceKey)
183- NavigableMap subMap
184- if (currentValue instanceof NavigableMap ) {
185- subMap = (NavigableMap )currentValue
186- }
187- else {
188- subMap = new NavigableMap ( (NavigableMap )targetMap. rootConfig, newPathList. asImmutable())
189- if (currentValue instanceof Map ) {
190- subMap. putAll((Map )currentValue)
173+ int subscriptStart = sourceKey. indexOf(' [' )
174+ int subscriptEnd = sourceKey. indexOf(' ]' )
175+ if (subscriptEnd > subscriptStart) {
176+ if (subscriptStart > -1 && subscriptEnd != sourceKey. length() - 1 ) {
177+ String k = sourceKey[0 .. < subscriptStart]
178+ String index = sourceKey[subscriptStart+1 .. < subscriptEnd]
179+ String remainder = sourceKey[subscriptEnd+2 .. -1 ]
180+ if (remainder) {
181+
182+ boolean isNumber = index. isNumber()
183+ if (isNumber) {
184+ int i = index. toInteger()
185+ def currentValue = targetMap. get(k)
186+ List list = currentValue instanceof List ? currentValue : []
187+ if (list. size() > i) {
188+ def v = list. get(i)
189+ if (v instanceof Map ) {
190+ ((Map )v). put(remainder, sourceValue)
191+ } else {
192+ Map newMap = [:]
193+ newMap. put(remainder, sourceValue)
194+ list. set(i, newMap)
195+ }
196+ } else {
197+ Map newMap = [:]
198+ newMap. put(remainder, sourceValue)
199+
200+ list. add(i, newMap)
201+ }
202+ targetMap. put(k, list)
203+ } else {
204+ def currentValue = targetMap. get(k)
205+ Map nestedMap = currentValue instanceof Map ? currentValue : [:]
206+ targetMap. put(k, nestedMap)
207+
208+ def v = nestedMap. get(index)
209+ if (v instanceof Map ) {
210+ ((Map )v). put(remainder, sourceValue)
211+ } else {
212+ Map newMap = [:]
213+ newMap. put(remainder, sourceValue)
214+ nestedMap. put(index, newMap)
215+ }
216+ }
217+ }
218+
219+ }
220+ } else {
221+ Object currentValue = targetMap. containsKey(sourceKey) ? targetMap. get(sourceKey) : null
222+ Object newValue
223+ if (sourceValue instanceof Map ) {
224+ List<String > newPathList = []
225+ newPathList. addAll( targetMap. getPath() )
226+ newPathList. add(sourceKey)
227+ NavigableMap subMap
228+ if (currentValue instanceof NavigableMap ) {
229+ subMap = (NavigableMap )currentValue
230+ }
231+ else {
232+ subMap = new NavigableMap ( (NavigableMap )targetMap. rootConfig, newPathList. asImmutable())
233+ if (currentValue instanceof Map ) {
234+ subMap. putAll((Map )currentValue)
235+ }
191236 }
237+ String newPath = path ? " ${ path} .${ sourceKey} " : sourceKey
238+ mergeMaps(rootMap, newPath , subMap, (Map )sourceValue, parseFlatKeys)
239+ newValue = subMap
240+ } else {
241+ newValue = sourceValue
192242 }
193- String newPath = path ? " ${ path} .${ sourceKey} " : sourceKey
194- mergeMaps(rootMap, newPath , subMap, (Map )sourceValue, parseFlatKeys)
195- newValue = subMap
196- } else {
197- newValue = sourceValue
198- }
199- if (isNestedSet && newValue == null ) {
200- if (path) {
243+ if (isNestedSet && newValue == null ) {
244+ if (path) {
201245
202- def subMap = rootMap. get(path)
203- if (subMap instanceof Map ) {
204- subMap. remove(sourceKey)
205- }
206- def keysToRemove = rootMap. keySet(). findAll() { String key ->
207- key. startsWith(" ${ path} ." )
246+ def subMap = rootMap. get(path)
247+ if (subMap instanceof Map ) {
248+ subMap. remove(sourceKey)
249+ }
250+ def keysToRemove = rootMap. keySet(). findAll() { String key ->
251+ key. startsWith(" ${ path} ." )
252+ }
253+ for (key in keysToRemove) {
254+ rootMap. remove(key)
255+ }
208256 }
209- for (key in keysToRemove) {
210- rootMap. remove(key)
257+ targetMap. remove(sourceKey)
258+ } else {
259+ if (path) {
260+ rootMap. put( " ${ path} .${ sourceKey} " . toString(), newValue )
211261 }
262+ mergeMapEntry(targetMap, sourceKey, newValue)
212263 }
213- targetMap. remove(sourceKey)
214- } else {
215- if (path) {
216- rootMap. put( " ${ path} .${ sourceKey} " . toString(), newValue )
217- }
218- mergeMapEntry(targetMap, sourceKey, newValue)
219264 }
220265 }
221266
@@ -518,44 +563,4 @@ class NavigableMap implements Map<String, Object>, Cloneable {
518563// }
519564 }
520565
521- @CompileDynamic
522- static Map collapseKeysWithSubscript (Map m ) {
523- Set<Map > keys = m. collect { k , v ->
524- if (k ==~ SUBSCRIPT_REGEX ) {
525- def matcher = k =~ SUBSCRIPT_REGEX
526- return [
527- subscript : matcher[0 ][1 ],
528- name : matcher[0 ][2 ]
529- ]
530- }
531- [subscript : null ,
532- name : k]
533- }
534- Map result = [:]
535- Set keyNames = keys. collect { it. name } as Set
536- for (key in keyNames) {
537- Map submap = keys. find { it. name == key }
538- if (submap. subscript == null ) {
539- result[key] = m[key]
540- } else {
541- Set<Map > submaps = keys. findAll { it. name == key }
542- List l = []
543- for (submapkey in submaps. collect { it. subscript }) {
544- Map mapofsubkeys = m. findAll { k , v -> k == submapkey }
545- l. addAll(mapofsubkeys. collect { k , v -> v })
546- mapofsubkeys = m. findAll { k , v -> k != submapkey && k. startsWith(submapkey) }
547- if (mapofsubkeys) {
548- Map subscriptMap = [:]
549- mapofsubkeys. each { k , v ->
550- String subkey = k. substring(submapkey. length() + " ." . length())
551- subscriptMap[subkey] = v
552- }
553- l << subscriptMap
554- }
555- }
556- result[key] = l
557- }
558- }
559- result
560- }
561566}
0 commit comments