001/*
002 * Copyright 2002-2010 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.context.support;
018
019import java.text.MessageFormat;
020import java.util.HashMap;
021import java.util.Locale;
022import java.util.Map;
023
024import org.springframework.util.Assert;
025
026/**
027 * Simple implementation of {@link org.springframework.context.MessageSource}
028 * which allows messages to be registered programmatically.
029 * This MessageSource supports basic internationalization.
030 *
031 * <p>Intended for testing rather than for use in production systems.
032 *
033 * @author Rod Johnson
034 * @author Juergen Hoeller
035 */
036public class StaticMessageSource extends AbstractMessageSource {
037
038        /** Map from 'code + locale' keys to message Strings */
039        private final Map<String, String> messages = new HashMap<String, String>();
040
041        private final Map<String, MessageFormat> cachedMessageFormats = new HashMap<String, MessageFormat>();
042
043
044        @Override
045        protected String resolveCodeWithoutArguments(String code, Locale locale) {
046                return this.messages.get(code + '_' + locale.toString());
047        }
048
049        @Override
050        protected MessageFormat resolveCode(String code, Locale locale) {
051                String key = code + '_' + locale.toString();
052                String msg = this.messages.get(key);
053                if (msg == null) {
054                        return null;
055                }
056                synchronized (this.cachedMessageFormats) {
057                        MessageFormat messageFormat = this.cachedMessageFormats.get(key);
058                        if (messageFormat == null) {
059                                messageFormat = createMessageFormat(msg, locale);
060                                this.cachedMessageFormats.put(key, messageFormat);
061                        }
062                        return messageFormat;
063                }
064        }
065
066        /**
067         * Associate the given message with the given code.
068         * @param code the lookup code
069         * @param locale the locale that the message should be found within
070         * @param msg the message associated with this lookup code
071         */
072        public void addMessage(String code, Locale locale, String msg) {
073                Assert.notNull(code, "Code must not be null");
074                Assert.notNull(locale, "Locale must not be null");
075                Assert.notNull(msg, "Message must not be null");
076                this.messages.put(code + '_' + locale.toString(), msg);
077                if (logger.isDebugEnabled()) {
078                        logger.debug("Added message [" + msg + "] for code [" + code + "] and Locale [" + locale + "]");
079                }
080        }
081
082        /**
083         * Associate the given message values with the given keys as codes.
084         * @param messages the messages to register, with messages codes
085         * as keys and message texts as values
086         * @param locale the locale that the messages should be found within
087         */
088        public void addMessages(Map<String, String> messages, Locale locale) {
089                Assert.notNull(messages, "Messages Map must not be null");
090                for (Map.Entry<String, String> entry : messages.entrySet()) {
091                        addMessage(entry.getKey(), locale, entry.getValue());
092                }
093        }
094
095
096        @Override
097        public String toString() {
098                return getClass().getName() + ": " + this.messages;
099        }
100
101}