jdaugherty commented on code in PR #16795:
URL: https://github.com/apache/grails-core/pull/16795#discussion_r4416192937
##########
grails-core/src/main/groovy/org/grails/spring/context/support/GrailsPlaceholderConfigurer.java:
##########
@@ -109,4 +149,35 @@ protected void visitMap(Map<?, ?> mapVal) {
// New in Spring 3.0: resolve placeholders in embedded values such as
annotation attributes.
beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
}
+
+ /**
+ * Presents each list of plain values in the environment under the name of
the list, its elements
+ * joined by commas.
+ */
+ private static final class ConfigurationListPropertySource extends
PropertySource<ConfigurableEnvironment> {
+
+ private final Binder binder;
+
+ ConfigurationListPropertySource(ConfigurableEnvironment environment) {
+ super(CONFIGURATION_LISTS_PROPERTY_SOURCE_NAME, environment);
+ // without a placeholder resolver: the placeholders in the
elements are resolved with the joined value
+ this.binder = new
Binder(ConfigurationPropertySources.get(environment));
+ }
+
+ @Override
+ public Object getProperty(String name) {
+ if (!ConfigurationPropertyName.isValid(name)) {
Review Comment:
Fixed in 40f143239e: the name is adapted with
`ConfigurationPropertyName.adapt(name, '.')` and passed to `Binder.bind` as a
`ConfigurationPropertyName`, with an `isEmpty()` guard in place of `isValid`.
Your four placeholders now resolve, and `${app.allowedOrigins}` reads an
`app.allowed-origins` key. The relaxed matching is noted in the Javadoc and in
the config guide paragraph.
##########
grails-core/src/test/groovy/grails/spring/GrailsPlaceholderConfigurerSpec.groovy:
##########
@@ -108,6 +119,155 @@ class GrailsPlaceholderConfigurerSpec extends
Specification {
bean.name == "test"
}
+
+ void "a placeholder naming a list of plain values resolves to the elements
of the list"() {
Review Comment:
Added in 40f143239e. One feature injects `grails.cors.allowedOrigins: [...]`
through `@Value('${grails.cors.allowedOrigins}')` into a `List<String>` and a
`String`. A data-driven feature reads `app.allowedOrigins` through
`${app.allowed-origins}` and `${app.allowedorigins}`, and `app.allowed-origins`
through `${app.allowedOrigins}`. On 7f3cf79db8 the camelCase `@Value` feature
and the `${app.allowedOrigins}` row fail; the kebab-case and lowercase
placeholders already passed there, since `isValid` accepted them and the binder
matched the camelCase key. All 15 features pass with the fix.
##########
grails-doc/src/en/guide/conf/config.adoc:
##########
@@ -165,9 +165,18 @@ To read a whole list, use
`grailsApplication.config.getProperty('grails.cors.all
`@ConfigurationProperties`. Spring's `Environment` exposes non-empty YAML
lists through indexed properties such as
`grails.cors.allowedOrigins[0]`. A list nested in a list uses one index per
level, such as `app.groups[0][1]`.
-Because the list itself is not a property of the `Environment`, a
`@Value('${grails.cors.allowedOrigins}')` placeholder
-cannot inject it, just as in a plain Spring Boot application. Bind the list
with `@ConfigurationProperties` or with Spring Boot's
-`Binder`, or write the value as one comma-separated string where a `@Value`
placeholder must read it.
+The list itself is not a property of the `Environment`, so
`environment.getProperty('grails.cors.allowedOrigins')`
+returns `null`, as in a plain Spring Boot application. A
`@Value('${grails.cors.allowedOrigins}')` placeholder, or any
Review Comment:
The code fix is in 40f143239e, so the
`@Value('${grails.cors.allowedOrigins}')` example resolves now. I added one
sentence to this paragraph saying the name is matched as
`@ConfigurationProperties` binding matches it, with
`${grails.cors.allowed-origins}` as the example.
--
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]