From a68ec76bb685bfda6ecd4bf008bf26db868faf8a Mon Sep 17 00:00:00 2001 From: Kedar Joshi Date: Mon, 2 Oct 2017 16:05:15 +0530 Subject: [PATCH 1/3] Adds support for useCodeAsDefaultMessage See gh-10466 --- .../MessageSourceAutoConfiguration.java | 1 + .../context/MessageSourceProperties.java | 13 ++++++++++++ .../MessageSourceAutoConfigurationTests.java | 21 +++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfiguration.java index 3bd237dcd9..1d3308f2e3 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfiguration.java @@ -75,6 +75,7 @@ public class MessageSourceAutoConfiguration { messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale()); messageSource.setCacheSeconds(properties.getCacheSeconds()); messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat()); + messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage()); return messageSource; } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java index b4a1fd94ba..e2328d99ea 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java @@ -22,6 +22,7 @@ import java.nio.charset.Charset; * Configuration properties for Message Source. * * @author Stephane Nicoll + * @author Kedar Joshi * @since 2.0.0 */ public class MessageSourceProperties { @@ -57,6 +58,11 @@ public class MessageSourceProperties { */ private boolean alwaysUseMessageFormat = false; + /** + * Set whether to use the message code as default message instead of throwing a NoSuchMessageException. + */ + private boolean useCodeAsDefaultMessage = false; + public String getBasename() { return this.basename; } @@ -97,4 +103,11 @@ public class MessageSourceProperties { this.alwaysUseMessageFormat = alwaysUseMessageFormat; } + public boolean isUseCodeAsDefaultMessage() { + return this.useCodeAsDefaultMessage; + } + + public void setUseCodeAsDefaultMessage(final boolean useCodeAsDefaultMessage) { + this.useCodeAsDefaultMessage = useCodeAsDefaultMessage; + } } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java index 19501894d5..dbe60d1e60 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java @@ -41,6 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Dave Syer * @author Eddú Meléndez * @author Stephane Nicoll + * @author Kedar Joshi */ public class MessageSourceAutoConfigurationTests { @@ -142,6 +143,26 @@ public class MessageSourceAutoConfigurationTests { .getPropertyValue("alwaysUseMessageFormat"); } + @Test + public void testUseCodeAsDefaultMessageDefault() throws Exception { + load("spring.messages.basename:test/messages"); + assertThat(isUseCodeAsDefaultMessage(this.context.getBean(MessageSource.class))) + .isFalse(); + } + + @Test + public void testUseCodeAsDefaultMessageOn() throws Exception { + load("spring.messages.basename:test/messages", + "spring.messages.use-code-as-default-message:true"); + assertThat(isUseCodeAsDefaultMessage(this.context.getBean(MessageSource.class))) + .isTrue(); + } + + private boolean isUseCodeAsDefaultMessage(MessageSource messageSource) { + return (boolean) new DirectFieldAccessor(messageSource) + .getPropertyValue("useCodeAsDefaultMessage"); + } + @Test public void existingMessageSourceIsPreferred() { this.context = new AnnotationConfigApplicationContext(); From 6c826ef0b6f512ac6d9411ff8affd0ffb064f448 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 2 Oct 2017 15:43:27 +0200 Subject: [PATCH 2/3] Polish "Adds support for useCodeAsDefaultMessage" Closes gh-10466 --- .../boot/autoconfigure/context/MessageSourceProperties.java | 4 +++- .../context/MessageSourceAutoConfigurationTests.java | 4 ++-- .../src/main/asciidoc/appendix-application-properties.adoc | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java index e2328d99ea..456be83100 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/MessageSourceProperties.java @@ -59,7 +59,8 @@ public class MessageSourceProperties { private boolean alwaysUseMessageFormat = false; /** - * Set whether to use the message code as default message instead of throwing a NoSuchMessageException. + * Set whether to use the message code as default message instead of throwing a + * "NoSuchMessageException". Recommended during development only. */ private boolean useCodeAsDefaultMessage = false; @@ -110,4 +111,5 @@ public class MessageSourceProperties { public void setUseCodeAsDefaultMessage(final boolean useCodeAsDefaultMessage) { this.useCodeAsDefaultMessage = useCodeAsDefaultMessage; } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java index dbe60d1e60..4c6c9135d5 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java @@ -144,14 +144,14 @@ public class MessageSourceAutoConfigurationTests { } @Test - public void testUseCodeAsDefaultMessageDefault() throws Exception { + public void testUseCodeAsDefaultMessageDefault() { load("spring.messages.basename:test/messages"); assertThat(isUseCodeAsDefaultMessage(this.context.getBean(MessageSource.class))) .isFalse(); } @Test - public void testUseCodeAsDefaultMessageOn() throws Exception { + public void testUseCodeAsDefaultMessageOn() { load("spring.messages.basename:test/messages", "spring.messages.use-code-as-default-message:true"); assertThat(isUseCodeAsDefaultMessage(this.context.getBean(MessageSource.class))) diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 6f7c6a968a..66fb7540a4 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -117,6 +117,7 @@ content into your application; rather pick only the properties that you need. spring.messages.cache-seconds=-1 # Loaded resource bundle files cache expiration, in seconds. When set to -1, bundles are cached forever. spring.messages.encoding=UTF-8 # Message bundles encoding. spring.messages.fallback-to-system-locale=true # Set whether to fall back to the system Locale if no files for a specific Locale have been found. + spring.messages.use-code-as-default-message=false # Set whether to use the message code as default message instead of throwing a "NoSuchMessageException". Recommended during development only. # OUTPUT spring.output.ansi.enabled=detect # Configure the ANSI output. From d778173089c93b65ee7aa1add4885cc5d4fe25a9 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 2 Oct 2017 15:56:09 +0200 Subject: [PATCH 3/3] Polish --- .../MessageSourceAutoConfigurationTests.java | 164 ++++++++---------- 1 file changed, 71 insertions(+), 93 deletions(-) diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java index 4c6c9135d5..fae2645057 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/MessageSourceAutoConfigurationTests.java @@ -18,17 +18,15 @@ package org.springframework.boot.autoconfigure.context; import java.util.Locale; -import org.junit.After; import org.junit.Ignore; import org.junit.Test; import org.springframework.beans.DirectFieldAccessor; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceResolvable; import org.springframework.context.NoSuchMessageException; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @@ -45,92 +43,89 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class MessageSourceAutoConfigurationTests { - private AnnotationConfigApplicationContext context; + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + MessageSourceAutoConfiguration.class)); - @After - public void closeContext() { - if (this.context != null) { - this.context.close(); - } + @Test + public void testDefaultMessageSource() { + this.contextRunner.run((context) -> + assertThat(context.getMessage("foo", null, "Foo message", Locale.UK)) + .isEqualTo("Foo message")); } @Test - public void testDefaultMessageSource() throws Exception { - load(); - assertThat(this.context.getMessage("foo", null, "Foo message", Locale.UK)) - .isEqualTo("Foo message"); + public void testMessageSourceCreated() { + this.contextRunner.withPropertyValues("spring.messages.basename:test/messages") + .run((context) -> assertThat(context.getMessage( + "foo", null, "Foo message", Locale.UK)).isEqualTo("bar")); } @Test - public void testMessageSourceCreated() throws Exception { - load("spring.messages.basename:test/messages"); - assertThat(this.context.getMessage("foo", null, "Foo message", Locale.UK)) - .isEqualTo("bar"); + public void testEncodingWorks() { + this.contextRunner.withPropertyValues("spring.messages.basename:test/swedish") + .run((context) -> assertThat(context.getMessage( + "foo", null, "Foo message", Locale.UK)).isEqualTo( + "Some text with some swedish öäå!")); } @Test - public void testEncodingWorks() throws Exception { - load("spring.messages.basename:test/swedish"); - assertThat(this.context.getMessage("foo", null, "Foo message", Locale.UK)) - .isEqualTo("Some text with some swedish öäå!"); + public void testMultipleMessageSourceCreated() { + this.contextRunner.withPropertyValues( + "spring.messages.basename:test/messages,test/messages2").run((context) -> { + assertThat(context.getMessage("foo", null, "Foo message", Locale.UK)) + .isEqualTo("bar"); + assertThat(context.getMessage("foo-foo", null, "Foo-Foo message", Locale.UK)) + .isEqualTo("bar-bar"); + }); } @Test - public void testMultipleMessageSourceCreated() throws Exception { - load("spring.messages.basename:test/messages,test/messages2"); - assertThat(this.context.getMessage("foo", null, "Foo message", Locale.UK)) - .isEqualTo("bar"); - assertThat(this.context.getMessage("foo-foo", null, "Foo-Foo message", Locale.UK)) - .isEqualTo("bar-bar"); - } - - @Test - public void testBadEncoding() throws Exception { - load("spring.messages.encoding:rubbish"); - // Bad encoding just means the messages are ignored - assertThat(this.context.getMessage("foo", null, "blah", Locale.UK)) - .isEqualTo("blah"); + public void testBadEncoding() { + this.contextRunner.withPropertyValues("spring.messages.encoding:rubbish") + .run((context) -> { + // Bad encoding just means the messages are ignored + assertThat(context.getMessage("foo", null, "blah", Locale.UK)) + .isEqualTo("blah"); + }); } @Test @Ignore("Expected to fail per gh-1075") - public void testMessageSourceFromPropertySourceAnnotation() throws Exception { - this.context = new AnnotationConfigApplicationContext(); - this.context.register(Config.class, MessageSourceAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); - assertThat(this.context.getMessage("foo", null, "Foo message", Locale.UK)) - .isEqualTo("bar"); + public void testMessageSourceFromPropertySourceAnnotation() { + this.contextRunner.withUserConfiguration(Config.class).run((context) -> + assertThat(context.getMessage("foo", null, "Foo message", Locale.UK)) + .isEqualTo("bar")); } @Test - public void testFallbackDefault() throws Exception { - load("spring.messages.basename:test/messages"); - assertThat(isFallbackToSystemLocale(this.context.getBean(MessageSource.class))) - .isTrue(); + public void testFallbackDefault() { + this.contextRunner.withPropertyValues("spring.messages.basename:test/messages") + .run((context) -> assertThat(isFallbackToSystemLocale( + context.getBean(MessageSource.class))).isTrue()); } @Test - public void testFallbackTurnOff() throws Exception { - load("spring.messages.basename:test/messages", - "spring.messages.fallback-to-system-locale:false"); - assertThat(isFallbackToSystemLocale(this.context.getBean(MessageSource.class))) - .isFalse(); + public void testFallbackTurnOff() { + this.contextRunner.withPropertyValues("spring.messages.basename:test/messages", + "spring.messages.fallback-to-system-locale:false").run((context) -> + assertThat(isFallbackToSystemLocale(context.getBean(MessageSource.class))) + .isFalse()); } @Test - public void testFormatMessageDefault() throws Exception { - load("spring.messages.basename:test/messages"); - assertThat(isAlwaysUseMessageFormat(this.context.getBean(MessageSource.class))) - .isFalse(); + public void testFormatMessageDefault() { + this.contextRunner.withPropertyValues("spring.messages.basename:test/messages") + .run((context) -> assertThat(isAlwaysUseMessageFormat( + context.getBean(MessageSource.class))).isFalse()); } @Test public void testFormatMessageOn() throws Exception { - load("spring.messages.basename:test/messages", - "spring.messages.always-use-message-format:true"); - assertThat(isAlwaysUseMessageFormat(this.context.getBean(MessageSource.class))) - .isTrue(); + this.contextRunner.withPropertyValues("spring.messages.basename:test/messages", + "spring.messages.always-use-message-format:true").run((context) -> + assertThat(isAlwaysUseMessageFormat(context.getBean(MessageSource.class))) + .isTrue()); } private boolean isFallbackToSystemLocale(MessageSource messageSource) { @@ -145,17 +140,17 @@ public class MessageSourceAutoConfigurationTests { @Test public void testUseCodeAsDefaultMessageDefault() { - load("spring.messages.basename:test/messages"); - assertThat(isUseCodeAsDefaultMessage(this.context.getBean(MessageSource.class))) - .isFalse(); + this.contextRunner.withPropertyValues("spring.messages.basename:test/messages") + .run((context) -> assertThat(isUseCodeAsDefaultMessage( + context.getBean(MessageSource.class))).isFalse()); } @Test public void testUseCodeAsDefaultMessageOn() { - load("spring.messages.basename:test/messages", - "spring.messages.use-code-as-default-message:true"); - assertThat(isUseCodeAsDefaultMessage(this.context.getBean(MessageSource.class))) - .isTrue(); + this.contextRunner.withPropertyValues("spring.messages.basename:test/messages", + "spring.messages.use-code-as-default-message:true").run((context) -> + assertThat(isUseCodeAsDefaultMessage( + context.getBean(MessageSource.class))).isTrue()); } private boolean isUseCodeAsDefaultMessage(MessageSource messageSource) { @@ -165,36 +160,19 @@ public class MessageSourceAutoConfigurationTests { @Test public void existingMessageSourceIsPreferred() { - this.context = new AnnotationConfigApplicationContext(); - this.context.register(CustomMessageSource.class, - MessageSourceAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); - assertThat(this.context.getMessage("foo", null, null, null)).isEqualTo("foo"); + this.contextRunner.withUserConfiguration(CustomMessageSource.class) + .run((context) -> assertThat(context.getMessage("foo", null, null, null)) + .isEqualTo("foo")); } @Test public void existingMessageSourceInParentIsIgnored() { - try (ConfigurableApplicationContext parent = new AnnotationConfigApplicationContext()) { - parent.refresh(); - this.context = new AnnotationConfigApplicationContext(); - this.context.setParent(parent); - TestPropertyValues.of("spring.messages.basename:test/messages") - .applyTo(this.context); - this.context.register(MessageSourceAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); - assertThat(this.context.getMessage("foo", null, "Foo message", Locale.UK)) - .isEqualTo("bar"); - } - } - - private void load(String... environment) { - this.context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of(environment).applyTo(this.context); - this.context.register(MessageSourceAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); + this.contextRunner.run((parent) -> { + this.contextRunner.withParent(parent) + .withPropertyValues("spring.messages.basename:test/messages") + .run((context) -> assertThat(context.getMessage( + "foo", null, "Foo message", Locale.UK)).isEqualTo("bar")); + }); } @Configuration