Skip to content

Commit 0b5457e

Browse files
committed
Ensure nested navigable maps are re-used. Fixes #10120
1 parent 49c0cee commit 0b5457e

File tree

2 files changed

+168
-3
lines changed

2 files changed

+168
-3
lines changed

grails-bootstrap/src/main/groovy/org/grails/config/NavigableMap.groovy

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,15 @@ class NavigableMap implements Map<String, Object>, Cloneable {
145145
List<String> newPathList = []
146146
newPathList.addAll( targetMap.getPath() )
147147
newPathList.add(sourceKey)
148-
NavigableMap subMap = new NavigableMap( (NavigableMap)targetMap.rootConfig, newPathList.asImmutable())
149-
if(currentValue instanceof Map) {
150-
subMap.putAll((Map)currentValue)
148+
NavigableMap subMap
149+
if(currentValue instanceof NavigableMap) {
150+
subMap = (NavigableMap)currentValue
151+
}
152+
else {
153+
subMap = new NavigableMap( (NavigableMap)targetMap.rootConfig, newPathList.asImmutable())
154+
if(currentValue instanceof Map) {
155+
subMap.putAll((Map)currentValue)
156+
}
151157
}
152158
String newPath = path ? "${path}.${sourceKey}" : sourceKey
153159
mergeMaps(rootMap, newPath , subMap, (Map)sourceValue, parseFlatKeys)
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package org.grails.config
2+
3+
import org.grails.config.yaml.YamlPropertySourceLoader
4+
import org.springframework.core.env.MutablePropertySources
5+
import org.springframework.core.io.ByteArrayResource
6+
import org.springframework.core.io.Resource
7+
import spock.lang.Specification
8+
9+
/**
10+
* Created by graemerocher on 29/08/2016.
11+
*/
12+
class NavigableMapNestedEqualitySpec extends Specification {
13+
14+
void "Test nested equality"() {
15+
given:
16+
Resource resource1 = new ByteArrayResource('''
17+
---
18+
grails:
19+
profile: web-plugin
20+
codegen:
21+
defaultPackage: grails.plugins.export
22+
info:
23+
app:
24+
name: 'export\'
25+
version: '2.0.0\'
26+
grailsVersion: '3.0.3.BUILD-SNAPSHOT\'
27+
spring:
28+
groovy:
29+
template:
30+
check-template-location: false
31+
32+
---
33+
grails:
34+
mime:
35+
disable:
36+
accept:
37+
header:
38+
userAgents:
39+
- Gecko
40+
- WebKit
41+
- Presto
42+
- Trident
43+
types:
44+
all: '*/*\'
45+
atom: application/atom+xml
46+
css: text/css
47+
csv: text/csv
48+
form: application/x-www-form-urlencoded
49+
html:
50+
- text/html
51+
- application/xhtml+xml
52+
js: text/javascript
53+
json:
54+
- application/json
55+
- text/json
56+
multipartForm: multipart/form-data
57+
rss: application/rss+xml
58+
text: text/plain
59+
hal:
60+
- application/hal+json
61+
- application/hal+xml
62+
xml:
63+
- text/xml
64+
- application/xml
65+
urlmapping:
66+
cache:
67+
maxsize: 1000
68+
controllers:
69+
defaultScope: singleton
70+
converters:
71+
encoding: UTF-8
72+
hibernate:
73+
cache:
74+
queries: false
75+
views:
76+
default:
77+
codec: html
78+
gsp:
79+
encoding: UTF-8
80+
htmlcodec: xml
81+
codecs:
82+
expression: html
83+
scriptlets: html
84+
taglib: none
85+
staticparts: none
86+
87+
---
88+
exporters:
89+
excelExporter: grails.plugins.export.exporter.DefaultExcelExporter
90+
csvExporter: grails.plugins.export.exporter.DefaultCSVExporter
91+
xmlExporter: grails.plugins.export.exporter.DefaultXMLExporter
92+
pdfExporter: grails.plugins.export.exporter.DefaultPDFExporter
93+
odsExporter: grails.plugins.export.exporter.DefaultODSExporter
94+
rtfExporter: grails.plugins.export.exporter.DefaultRTFExporter
95+
96+
---
97+
dataSource:
98+
pooled: true
99+
jmxExport: true
100+
driverClassName: org.h2.Driver
101+
username: sa
102+
password:
103+
104+
environments:
105+
development:
106+
dataSource:
107+
dbCreate: create-drop
108+
url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
109+
test:
110+
dataSource:
111+
dbCreate: update
112+
url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
113+
production:
114+
dataSource:
115+
dbCreate: update
116+
url: jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
117+
properties:
118+
jmxEnabled: true
119+
initialSize: 5
120+
maxActive: 50
121+
minIdle: 5
122+
maxIdle: 25
123+
maxWait: 10000
124+
maxAge: 600000
125+
timeBetweenEvictionRunsMillis: 5000
126+
minEvictableIdleTimeMillis: 60000
127+
validationQuery: SELECT 1
128+
validationQueryTimeout: 3
129+
validationInterval: 15000
130+
testOnBorrow: true
131+
testWhileIdle: true
132+
testOnReturn: false
133+
jdbcInterceptors: ConnectionState
134+
defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
135+
136+
'''.bytes, "test.yml")
137+
138+
Resource resource2 = new ByteArrayResource('''
139+
grails:
140+
mime:
141+
types:
142+
form: application/x-www-form-urlencoded
143+
'''.bytes, "test.yml")
144+
145+
def propertySourceLoader = new YamlPropertySourceLoader()
146+
def yamlPropertiesSource1 = propertySourceLoader.load('foo-plugin-environments.yml', resource1, null, true, Arrays.asList("dataSource", "hibernate"))
147+
def yamlPropertiesSource2 = propertySourceLoader.load('bar-plugin-environments.yml', resource2, null, true, Arrays.asList("dataSource", "hibernate"))
148+
def propertySources = new MutablePropertySources()
149+
propertySources.addFirst(yamlPropertiesSource1)
150+
propertySources.addFirst(yamlPropertiesSource2)
151+
def config = new PropertySourcesConfig(propertySources)
152+
153+
expect:
154+
config.getProperty('grails.mime.types', Map) == ( config.grails.mime.types )
155+
config.getProperty('grails.mime.types', Map).is( config.grails.mime.types )
156+
157+
158+
}
159+
}

0 commit comments

Comments
 (0)