1 16 17 package org.springframework.context.support; 18 19 import java.text.MessageFormat ; 20 import java.util.HashMap ; 21 import java.util.Locale ; 22 import java.util.Map ; 23 import java.util.MissingResourceException ; 24 import java.util.ResourceBundle ; 25 26 import org.springframework.beans.factory.BeanClassLoaderAware; 27 import org.springframework.util.Assert; 28 import org.springframework.util.ClassUtils; 29 import org.springframework.util.StringUtils; 30 31 57 public class ResourceBundleMessageSource extends AbstractMessageSource implements BeanClassLoaderAware { 58 59 private String [] basenames = new String [0]; 60 61 private ClassLoader bundleClassLoader; 62 63 private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); 64 65 72 private final Map cachedResourceBundles = new HashMap (); 73 74 82 private final Map cachedBundleMessageFormats = new HashMap (); 83 84 85 97 public void setBasename(String basename) { 98 setBasenames(new String [] {basename}); 99 } 100 101 114 public void setBasenames(String [] basenames) { 115 if (basenames != null) { 116 this.basenames = new String [basenames.length]; 117 for (int i = 0; i < basenames.length; i++) { 118 String basename = basenames[i]; 119 Assert.hasText(basename, "Basename must not be empty"); 120 this.basenames[i] = basename.trim(); 121 } 122 } 123 else { 124 this.basenames = new String [0]; 125 } 126 } 127 128 136 public void setBundleClassLoader(ClassLoader classLoader) { 137 this.bundleClassLoader = classLoader; 138 } 139 140 145 protected ClassLoader getBundleClassLoader() { 146 return (this.bundleClassLoader != null ? this.bundleClassLoader : this.beanClassLoader); 147 } 148 149 public void setBeanClassLoader(ClassLoader classLoader) { 150 this.beanClassLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader()); 151 } 152 153 154 158 protected String resolveCodeWithoutArguments(String code, Locale locale) { 159 String result = null; 160 for (int i = 0; result == null && i < this.basenames.length; i++) { 161 ResourceBundle bundle = getResourceBundle(this.basenames[i], locale); 162 if (bundle != null) { 163 result = getStringOrNull(bundle, code); 164 } 165 } 166 return result; 167 } 168 169 173 protected MessageFormat resolveCode(String code, Locale locale) { 174 MessageFormat messageFormat = null; 175 for (int i = 0; messageFormat == null && i < this.basenames.length; i++) { 176 ResourceBundle bundle = getResourceBundle(this.basenames[i], locale); 177 if (bundle != null) { 178 messageFormat = getMessageFormat(bundle, code, locale); 179 } 180 } 181 return messageFormat; 182 } 183 184 185 193 protected ResourceBundle getResourceBundle(String basename, Locale locale) { 194 synchronized (this.cachedResourceBundles) { 195 Map localeMap = (Map ) this.cachedResourceBundles.get(basename); 196 if (localeMap != null) { 197 ResourceBundle bundle = (ResourceBundle ) localeMap.get(locale); 198 if (bundle != null) { 199 return bundle; 200 } 201 } 202 try { 203 ResourceBundle bundle = doGetBundle(basename, locale); 204 if (localeMap == null) { 205 localeMap = new HashMap (); 206 this.cachedResourceBundles.put(basename, localeMap); 207 } 208 localeMap.put(locale, bundle); 209 return bundle; 210 } 211 catch (MissingResourceException ex) { 212 if (logger.isWarnEnabled()) { 213 logger.warn("ResourceBundle [" + basename + "] not found for MessageSource: " + ex.getMessage()); 214 } 215 return null; 218 } 219 } 220 } 221 222 231 protected ResourceBundle doGetBundle(String basename, Locale locale) throws MissingResourceException { 232 return ResourceBundle.getBundle(basename, locale, getBundleClassLoader()); 233 } 234 235 245 protected MessageFormat getMessageFormat(ResourceBundle bundle, String code, Locale locale) 246 throws MissingResourceException { 247 248 synchronized (this.cachedBundleMessageFormats) { 249 Map codeMap = (Map ) this.cachedBundleMessageFormats.get(bundle); 250 Map localeMap = null; 251 if (codeMap != null) { 252 localeMap = (Map ) codeMap.get(code); 253 if (localeMap != null) { 254 MessageFormat result = (MessageFormat ) localeMap.get(locale); 255 if (result != null) { 256 return result; 257 } 258 } 259 } 260 261 String msg = getStringOrNull(bundle, code); 262 if (msg != null) { 263 if (codeMap == null) { 264 codeMap = new HashMap (); 265 this.cachedBundleMessageFormats.put(bundle, codeMap); 266 } 267 if (localeMap == null) { 268 localeMap = new HashMap (); 269 codeMap.put(code, localeMap); 270 } 271 MessageFormat result = createMessageFormat(msg, locale); 272 localeMap.put(locale, result); 273 return result; 274 } 275 276 return null; 277 } 278 } 279 280 private String getStringOrNull(ResourceBundle bundle, String key) { 281 try { 282 return bundle.getString(key); 283 } 284 catch (MissingResourceException ex) { 285 return null; 288 } 289 } 290 291 292 295 public String toString() { 296 return getClass().getName() + ": basenames=[" + 297 StringUtils.arrayToCommaDelimitedString(this.basenames) + "]"; 298 } 299 300 } 301 | Popular Tags |