/* * Copyright 2008 biaoping.yin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.frameworkset.spi.support; import java.text.MessageFormat; import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.apache.log4j.Logger; /** * <p> * Title: MessageSourceSupport.java * </p> * <p> * Description: * </p> * <p> * bboss workgroup * </p> * <p> * Copyright (c) 2007 * </p> * * @Date 2010-9-24 下午05:05:18 * @author biaoping.yin * @version 1.0 */ public abstract class MessageSourceSupport { /** Logger available to subclasses */ protected static final Logger logger = Logger .getLogger(MessageSourceSupport.class); private boolean alwaysUseMessageFormat = false; /** * Cache to hold already generated MessageFormats per message. Used for * passed-in default messages. MessageFormats for resolved codes are cached * on a specific basis in subclasses. */ private final Map cachedMessageFormats = new HashMap(); /** * Set whether to always apply the MessageFormat rules, parsing even * messages without arguments. * <p> * Default is "false": Messages without arguments are by default returned * as-is, without parsing them through MessageFormat. Set this to "true" to * enforce MessageFormat for all messages, expecting all message texts to be * written with MessageFormat escaping. * <p> * For example, MessageFormat expects a single quote to be escaped as "''". * If your message texts are all written with such escaping, even when not * defining argument placeholders, you need to set this flag to "true". * Else, only message texts with actual arguments are supposed to be written * with MessageFormat escaping. * * @see java.text.MessageFormat */ public void setAlwaysUseMessageFormat(boolean alwaysUseMessageFormat) { this.alwaysUseMessageFormat = alwaysUseMessageFormat; } /** * Return whether to always apply the MessageFormat rules, parsing even * messages without arguments. */ protected boolean isAlwaysUseMessageFormat() { return this.alwaysUseMessageFormat; } /** * Format the given message String, using cached MessageFormats. By default * invoked for passed-in default messages, to resolve any argument * placeholders found in them. * * @param msg * the message to format * @param args * array of arguments that will be filled in for params within * the message, or <code>null</code> if none. * @param locale * the Locale used for formatting * @return the formatted message (with resolved arguments) */ protected String formatMessage(String msg, Object[] args, Locale locale) { if (msg == null || (!this.alwaysUseMessageFormat && (args == null || args.length == 0))) { return msg; } MessageFormat messageFormat = (MessageFormat) this.cachedMessageFormats.get(msg); if (messageFormat == null) { synchronized (this.cachedMessageFormats) { messageFormat = (MessageFormat) this.cachedMessageFormats.get(msg); if (messageFormat == null) { messageFormat = createMessageFormat(msg, locale); this.cachedMessageFormats.put(msg, messageFormat); } } } synchronized (messageFormat) { return messageFormat.format(resolveArguments(args, locale)); } } /** * Create a MessageFormat for the given message and Locale. * * @param msg * the message to create a MessageFormat for * @param locale * the Locale to create a MessageFormat for * @return the MessageFormat instance */ protected static MessageFormat createMessageFormat(String msg, Locale locale) { if (logger.isDebugEnabled()) { logger.debug("Creating MessageFormat for pattern [" + msg + "] and locale '" + locale + "'"); } return new MessageFormat((msg != null ? msg : ""), locale); } /** * Template method for resolving argument objects. * <p> * The default implementation simply returns the given argument array as-is. * Can be overridden in subclasses in order to resolve special argument * types. * * @param args * the original argument array * @param locale * the Locale to resolve against * @return the resolved argument array */ protected Object[] resolveArguments(Object[] args, Locale locale) { return args; } /** * Render the given default message String. The default message is passed in * as specified by the caller and can be rendered into a fully formatted * default message shown to the user. * <p> * The default implementation passes the String to * <code>formatMessage</code>, resolving any argument placeholders found in * them. Subclasses may override this method to plug in custom processing of * default messages. * * @param defaultMessage * the passed-in default message String * @param args * array of arguments that will be filled in for params within * the message, or <code>null</code> if none. * @param locale * the Locale used for formatting * @return the rendered default message (with resolved arguments) * @see #formatMessage(String, Object[], java.util.Locale) */ protected String renderDefaultMessage(String defaultMessage, Object[] args, Locale locale) { return formatMessage(defaultMessage, args, locale); } }