From 4dc03f7c155017b5102f6b62fec84ef56c2e56eb Mon Sep 17 00:00:00 2001 From: Robert Oschwald Date: Mon, 3 May 2021 12:53:53 +0200 Subject: [PATCH 1/3] GRAILS-11795 preserve order of bean-defined basenames. - fixes GRAILS-11795 --- ...PluginAwareResourceBundleMessageSource.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) 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 34f6f9d365a..61648a675e3 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 @@ -39,10 +39,7 @@ import java.io.File; import java.io.FilenameFilter; import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Properties; +import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -65,6 +62,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() { } @@ -86,6 +84,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; @@ -148,8 +152,10 @@ public boolean accept(File dir, String name) { basenames.add(baseName); } - setBasenames(basenames.toArray( new String[basenames.size()])); - + List mergedBasenames = Arrays.asList(basenamesDefinition); + basenames.removeAll(mergedBasenames); + mergedBasenames.addAll(basenames); + super.setBasenames(mergedBasenames.toArray(new String[0])); } From bac5956cf224cbe5615a7aad11e0776fdb641db2 Mon Sep 17 00:00:00 2001 From: Robert Oschwald Date: Tue, 4 May 2021 18:38:51 +0200 Subject: [PATCH 2/3] Avoid UnsupportedOperationException with some JDKs --- .../context/support/PluginAwareResourceBundleMessageSource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 61648a675e3..ebf28a2a538 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 @@ -152,7 +152,7 @@ public boolean accept(File dir, String name) { basenames.add(baseName); } - List mergedBasenames = Arrays.asList(basenamesDefinition); + List mergedBasenames = new ArrayList<>(Arrays.asList(basenamesDefinition)); basenames.removeAll(mergedBasenames); mergedBasenames.addAll(basenames); super.setBasenames(mergedBasenames.toArray(new String[0])); From b1f1dbb2938f59d457c8bee9198bc37067950c20 Mon Sep 17 00:00:00 2001 From: Robert Oschwald Date: Mon, 19 May 2025 09:34:14 +0200 Subject: [PATCH 3/3] Test-Case for GRAILS-11795 fix --- .../ResourceBundleMessageSourceSpec.groovy | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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 3614f9da33b..a39224a6b53 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 @@ -12,10 +12,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')) } @@ -35,6 +37,22 @@ class ResourceBundleMessageSourceSpec extends Specification { messageSource.getBundleCodes(locale,'other') == (['bar'] as Set) messageSource.getBundleCodes(locale,'messages','other') == (['foo','bar'] as Set) } + + void 'Check method to verify ResourceBundle ordering prioritizes application over e.g. 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