1 16 17 package org.springframework.context.support; 18 19 import java.text.MessageFormat ; 20 import java.util.ArrayList ; 21 import java.util.HashMap ; 22 import java.util.List ; 23 import java.util.Locale ; 24 import java.util.Map ; 25 26 import org.apache.commons.logging.Log; 27 import org.apache.commons.logging.LogFactory; 28 29 import org.springframework.context.HierarchicalMessageSource; 30 import org.springframework.context.MessageSource; 31 import org.springframework.context.MessageSourceResolvable; 32 import org.springframework.context.NoSuchMessageException; 33 import org.springframework.util.ObjectUtils; 34 35 68 public abstract class AbstractMessageSource implements HierarchicalMessageSource { 69 70 71 protected final Log logger = LogFactory.getLog(getClass()); 72 73 private MessageSource parentMessageSource; 74 75 private boolean useCodeAsDefaultMessage = false; 76 77 private boolean alwaysUseMessageFormat = false; 78 79 84 private final Map cachedMessageFormats = new HashMap (); 85 86 87 public void setParentMessageSource(MessageSource parent) { 88 this.parentMessageSource = parent; 89 } 90 91 public MessageSource getParentMessageSource() { 92 return parentMessageSource; 93 } 94 95 113 public void setUseCodeAsDefaultMessage(boolean useCodeAsDefaultMessage) { 114 this.useCodeAsDefaultMessage = useCodeAsDefaultMessage; 115 } 116 117 125 protected boolean isUseCodeAsDefaultMessage() { 126 return useCodeAsDefaultMessage; 127 } 128 129 143 public void setAlwaysUseMessageFormat(boolean alwaysUseMessageFormat) { 144 this.alwaysUseMessageFormat = alwaysUseMessageFormat; 145 } 146 147 151 protected boolean isAlwaysUseMessageFormat() { 152 return alwaysUseMessageFormat; 153 } 154 155 156 public final String getMessage(String code, Object [] args, String defaultMessage, Locale locale) { 157 String msg = getMessageInternal(code, args, locale); 158 if (msg != null) { 159 return msg; 160 } 161 if (defaultMessage == null) { 162 String fallback = getDefaultMessage(code); 163 if (fallback != null) { 164 return fallback; 165 } 166 } 167 return renderDefaultMessage(defaultMessage, args, locale); 168 } 169 170 public final String getMessage(String code, Object [] args, Locale locale) throws NoSuchMessageException { 171 String msg = getMessageInternal(code, args, locale); 172 if (msg != null) { 173 return msg; 174 } 175 String fallback = getDefaultMessage(code); 176 if (fallback != null) { 177 return fallback; 178 } 179 throw new NoSuchMessageException(code, locale); 180 } 181 182 public final String getMessage(MessageSourceResolvable resolvable, Locale locale) 183 throws NoSuchMessageException { 184 185 String [] codes = resolvable.getCodes(); 186 if (codes == null) { 187 codes = new String [0]; 188 } 189 for (int i = 0; i < codes.length; i++) { 190 String msg = getMessageInternal(codes[i], resolvable.getArguments(), locale); 191 if (msg != null) { 192 return msg; 193 } 194 } 195 if (resolvable.getDefaultMessage() != null) { 196 return renderDefaultMessage(resolvable.getDefaultMessage(), resolvable.getArguments(), locale); 197 } 198 if (codes.length > 0) { 199 String fallback = getDefaultMessage(codes[0]); 200 if (fallback != null) { 201 return fallback; 202 } 203 } 204 throw new NoSuchMessageException(codes.length > 0 ? codes[codes.length - 1] : null, locale); 205 } 206 207 208 222 protected String getMessageInternal(String code, Object [] args, Locale locale) { 223 if (code == null) { 224 return null; 225 } 226 if (locale == null) { 227 locale = Locale.getDefault(); 228 } 229 Object [] argsToUse = args; 230 231 if (!isAlwaysUseMessageFormat() && ObjectUtils.isEmpty(args)) { 232 String message = resolveCodeWithoutArguments(code, locale); 237 if (message != null) { 238 return message; 239 } 240 } 241 242 else { 243 argsToUse = resolveArguments(args, locale); 247 248 MessageFormat messageFormat = resolveCode(code, locale); 249 if (messageFormat != null) { 250 synchronized (messageFormat) { 251 return messageFormat.format(argsToUse); 252 } 253 } 254 } 255 256 return getMessageFromParent(code, argsToUse, locale); 258 } 259 260 269 protected String getMessageFromParent(String code, Object [] args, Locale locale) { 270 MessageSource parent = getParentMessageSource(); 271 if (parent != null) { 272 if (parent instanceof AbstractMessageSource) { 273 return ((AbstractMessageSource) parent).getMessageInternal(code, args, locale); 276 } 277 else { 278 return parent.getMessage(code, args, null, locale); 280 } 281 } 282 return null; 284 } 285 286 297 protected String getDefaultMessage(String code) { 298 if (isUseCodeAsDefaultMessage()) { 299 return code; 300 } 301 return null; 302 } 303 304 305 319 protected String renderDefaultMessage(String defaultMessage, Object [] args, Locale locale) { 320 return formatMessage(defaultMessage, args, locale); 321 } 322 323 333 protected String formatMessage(String msg, Object [] args, Locale locale) { 334 if (msg == null || (!this.alwaysUseMessageFormat && (args == null || args.length == 0))) { 335 return msg; 336 } 337 MessageFormat messageFormat = null; 338 synchronized (this.cachedMessageFormats) { 339 messageFormat = (MessageFormat ) this.cachedMessageFormats.get(msg); 340 if (messageFormat == null) { 341 messageFormat = createMessageFormat(msg, locale); 342 this.cachedMessageFormats.put(msg, messageFormat); 343 } 344 } 345 synchronized (messageFormat) { 346 return messageFormat.format(resolveArguments(args, locale)); 347 } 348 } 349 350 359 protected MessageFormat createMessageFormat(String msg, Locale locale) { 360 if (logger.isDebugEnabled()) { 361 logger.debug("Creating MessageFormat for pattern [" + msg + "] and locale '" + locale + "'"); 362 } 363 MessageFormat messageFormat = new MessageFormat (""); 364 messageFormat.setLocale(locale); 365 if (msg != null) { 366 messageFormat.applyPattern(msg); 367 } 368 return messageFormat; 369 } 370 371 372 380 protected Object [] resolveArguments(Object [] args, Locale locale) { 381 if (args == null) { 382 return new Object [0]; 383 } 384 List resolvedArgs = new ArrayList (args.length); 385 for (int i = 0; i < args.length; i++) { 386 if (args[i] instanceof MessageSourceResolvable) { 387 resolvedArgs.add(getMessage((MessageSourceResolvable) args[i], locale)); 388 } 389 else { 390 resolvedArgs.add(args[i]); 391 } 392 } 393 return resolvedArgs.toArray(new Object [resolvedArgs.size()]); 394 } 395 396 415 protected String resolveCodeWithoutArguments(String code, Locale locale) { 416 MessageFormat messageFormat = resolveCode(code, locale); 417 if (messageFormat != null) { 418 synchronized (messageFormat) { 419 return messageFormat.format(new Object [0]); 420 } 421 } 422 return null; 423 } 424 425 438 protected abstract MessageFormat resolveCode(String code, Locale locale); 439 440 } 441 | Popular Tags |