diff --git a/grails-core/src/main/groovy/org/grails/spring/context/support/PluginAwareResourceBundleMessageSource.java b/grails-core/src/main/groovy/org/grails/spring/context/support/PluginAwareResourceBundleMessageSource.java index b070f4cffde..d1d0f9500ad 100644 --- a/grails-core/src/main/groovy/org/grails/spring/context/support/PluginAwareResourceBundleMessageSource.java +++ b/grails-core/src/main/groovy/org/grails/spring/context/support/PluginAwareResourceBundleMessageSource.java @@ -43,6 +43,7 @@ import java.io.FilenameFilter; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.Properties; @@ -68,6 +69,7 @@ public class PluginAwareResourceBundleMessageSource extends ReloadableResourceBu private long pluginCacheMillis = Long.MIN_VALUE; private boolean searchClasspath = false; private String messageBundleLocationPattern = "classpath*:*.properties"; + String[] basenamesDefinition = {}; public PluginAwareResourceBundleMessageSource() { } @@ -89,6 +91,12 @@ public void setResourceResolver(PathMatchingResourcePatternResolver resourceReso this.resourceResolver = resourceResolver; } + @Override + public void setBasenames(String... basenames) { + basenamesDefinition = basenames; + super.setBasenames(basenames); + } + public void afterPropertiesSet() throws Exception { if (pluginCacheMillis == Long.MIN_VALUE) { pluginCacheMillis = cacheMillis; @@ -151,8 +159,10 @@ public boolean accept(File dir, String name) { basenames.add(baseName); } - setBasenames(basenames.toArray( new String[basenames.size()])); - + List mergedBasenames = new ArrayList<>(Arrays.asList(basenamesDefinition)); + basenames.removeAll(mergedBasenames); + mergedBasenames.addAll(basenames); + super.setBasenames(mergedBasenames.toArray(new String[0])); } diff --git a/grails-core/src/test/groovy/org/grails/spring/context/ResourceBundleMessageSourceSpec.groovy b/grails-core/src/test/groovy/org/grails/spring/context/ResourceBundleMessageSourceSpec.groovy index 7deed4e8fcd..b44734e0ff8 100644 --- a/grails-core/src/test/groovy/org/grails/spring/context/ResourceBundleMessageSourceSpec.groovy +++ b/grails-core/src/test/groovy/org/grails/spring/context/ResourceBundleMessageSourceSpec.groovy @@ -30,10 +30,12 @@ class ResourceBundleMessageSourceSpec extends Specification { void setup(){ messages = new TestResource('messages.properties','''\ foo=bar + shared.message=Messages Message '''.stripIndent().getBytes('UTF-8')) other = new TestResource('other.properties','''\ bar=foo + shared.message=Other Message '''.stripIndent().getBytes('UTF-8')) } @@ -49,11 +51,27 @@ class ResourceBundleMessageSourceSpec extends Specification { messageSource.setBasenames('messages','other') def locale = Locale.default expect: - messageSource.getBundleCodes(locale,'messages') == (['foo'] as Set) - messageSource.getBundleCodes(locale,'other') == (['bar'] as Set) - messageSource.getBundleCodes(locale,'messages','other') == (['foo','bar'] as Set) + messageSource.getBundleCodes(locale,'messages') == (['foo', 'shared.message'] as Set) + messageSource.getBundleCodes(locale,'other') == (['bar', 'shared.message'] as Set) + messageSource.getBundleCodes(locale,'messages','other') == (['foo','bar', 'shared.message'] as Set) } + void 'Check method to verify ResourceBundle ordering prioritizes application over plugin messages'(){ + given: + def messageSource = new ReloadableResourceBundleMessageSource( + resourceLoader: new DefaultResourceLoader(){ + Resource getResourceByPath(String path){ + path.startsWith('messages') ? messages:other + } + } + ) + messageSource.setBasenames('other', 'messages') + def locale = Locale.default + expect: "other messages override plugin messages" + messageSource.getMessage('shared.message', null, locale) == 'Other Message' + messageSource.getMessage('foo', null, locale) == 'bar' + } + class TestResource extends ByteArrayResource{ String filename