jamesfredley commented on code in PR #16732:
URL: https://github.com/apache/grails-core/pull/16732#discussion_r4374100567
##########
grails-bootstrap/src/main/groovy/org/grails/config/NavigableMap.groovy:
##########
@@ -262,27 +957,61 @@ class NavigableMap implements Map<String, Object>,
Cloneable {
if (submap instanceof Map) {
return navigateMap((Map<String, Object>) submap, path.tail())
}
- return submap
+ return null
}
}
/**
* Sets a value in a list (numeric index) or map (other index) at the
given subscript, creating
* the container when the current value is not one. The text following the
subscript is either
* empty, further subscripts such as {@code [1]} for a list nested in a
list, or a {@code .name}
- * remainder stored as a key of a map element.
+ * remainder stored as a key of a map element. A container that already
holds the object is left
+ * as it is, so a merge of the same entries again, as a config merges its
property sources again,
+ * writes nothing into it. A container that refuses the write, such as a
list {@code application.groovy}
+ * built with {@code asImmutable()}, is replaced by a copy that holds it.
The index of a map is its key as
+ * written, a dot in it included, in a block as in any other map.
*/
private Object setSubscriptValue(Object currentValue, String index, String
rest, Object sourceValue) {
- if (index.isNumber()) {
+ if (index ==~ /\d+/) {
List list = currentValue instanceof List ? (List) currentValue : []
int i = index.toInteger()
- fill(list, i, null)
- list.set(i, subscriptElementValue(list.get(i), rest, sourceValue))
- return list
+ boolean held = i < list.size()
+ Object element = held ? list.get(i) : null
+ Object newElement = subscriptElementValue(element, rest,
sourceValue)
+ if (held && element.is(newElement)) {
+ return list
+ }
+ return writeElement(list, i, newElement)
+ }
+ if (currentValue instanceof NavigableMap) {
+ // the entry a read of the key finds: the one held under the key
as written, or else the one at the
+ // path it names, as a dotted key of application.yml is merged; a
new entry is held as written
+ NavigableMap block = (NavigableMap) currentValue
+ if (!block.delegateMap.containsKey(index) &&
!ABSENT.is(block.atPath(index))) {
Review Comment:
If `app.routes.extra` is merged first, the container is already a block.
Writing `app.routes[/api/**]` then stores the entry without its bracketed name.
The property source exposes `app.routes./api/**`, and Spring binds the key as
`api`.
Keep the bracketed name when the entry is added to an existing block, not
only to a subscript map. Please merge `extra` first and assert the bound key is
`/api/**`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]