From 9a04191c2b6ffad148359ae4214d86bf90d60481 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 3 Jan 2013 16:32:31 +0100 Subject: [PATCH] MessageSourceResourceBundle overrides JDK 1.6 containsKey method, avoiding NPE in getKeys Issue: SPR-10136 --- .../support/MessageSourceResourceBundle.java | 33 ++++++++++++++----- .../ResourceBundleMessageSourceTests.java | 17 ++++++++-- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/org.springframework.context/src/main/java/org/springframework/context/support/MessageSourceResourceBundle.java b/org.springframework.context/src/main/java/org/springframework/context/support/MessageSourceResourceBundle.java index c5fe46acf5..605aa72e87 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/support/MessageSourceResourceBundle.java +++ b/org.springframework.context/src/main/java/org/springframework/context/support/MessageSourceResourceBundle.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,12 +67,12 @@ public class MessageSourceResourceBundle extends ResourceBundle { /** * This implementation resolves the code in the MessageSource. - * Returns null if the message could not be resolved. + * Returns {@code null} if the message could not be resolved. */ @Override - protected Object handleGetObject(String code) { + protected Object handleGetObject(String key) { try { - return this.messageSource.getMessage(code, null, this.locale); + return this.messageSource.getMessage(key, null, this.locale); } catch (NoSuchMessageException ex) { return null; @@ -80,17 +80,34 @@ public class MessageSourceResourceBundle extends ResourceBundle { } /** - * This implementation returns null, as a MessageSource does - * not allow for enumerating the defined message codes. + * This implementation checks whether the target MessageSource can resolve + * a message for the given key, translating {@code NoSuchMessageException} + * accordingly. In contrast to ResourceBundle's default implementation in + * JDK 1.6, this does not rely on the capability to enumerate message keys. + */ + @Override + public boolean containsKey(String key) { + try { + this.messageSource.getMessage(key, null, this.locale); + return true; + } + catch (NoSuchMessageException ex) { + return false; + } + } + + /** + * This implementation throws {@code UnsupportedOperationException}, + * as a MessageSource does not allow for enumerating the defined message codes. */ @Override public Enumeration getKeys() { - return null; + throw new UnsupportedOperationException("MessageSourceResourceBundle does not support enumerating its keys"); } /** * This implementation exposes the specified Locale for introspection - * through the standard ResourceBundle.getLocale() method. + * through the standard {@code ResourceBundle.getLocale()} method. */ @Override public Locale getLocale() { diff --git a/org.springframework.context/src/test/java/org/springframework/context/support/ResourceBundleMessageSourceTests.java b/org.springframework.context/src/test/java/org/springframework/context/support/ResourceBundleMessageSourceTests.java index 8a462c0425..c0121a4a2d 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/support/ResourceBundleMessageSourceTests.java +++ b/org.springframework.context/src/test/java/org/springframework/context/support/ResourceBundleMessageSourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -115,8 +115,8 @@ public class ResourceBundleMessageSourceTests extends TestCase { if (alwaysUseMessageFormat) { pvs.add("alwaysUseMessageFormat", Boolean.TRUE); } - Class clazz = reloadable ? - (Class) ReloadableResourceBundleMessageSource.class : ResourceBundleMessageSource.class; + Class clazz = reloadable ? + (Class) ReloadableResourceBundleMessageSource.class : ResourceBundleMessageSource.class; ac.registerSingleton("messageSource", clazz, pvs); ac.refresh(); @@ -340,6 +340,17 @@ public class ResourceBundleMessageSourceTests extends TestCase { assertEquals(0, filenames.size()); } + public void testMessageSourceResourceBundle() { + ResourceBundleMessageSource ms = new ResourceBundleMessageSource(); + ms.setBasename("org/springframework/context/support/messages"); + MessageSourceResourceBundle rbe = new MessageSourceResourceBundle(ms, Locale.ENGLISH); + assertEquals("message1", rbe.getString("code1")); + assertTrue(rbe.containsKey("code1")); + MessageSourceResourceBundle rbg = new MessageSourceResourceBundle(ms, Locale.GERMAN); + assertEquals("nachricht2", rbg.getString("code2")); + assertTrue(rbg.containsKey("code2")); + } + @Override protected void tearDown() throws Exception { if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_16) {