jp.terasoluna.fw.message.DataSourceMessageSource.java Source code

Java tutorial

Introduction

Here is the source code for jp.terasoluna.fw.message.DataSourceMessageSource.java

Source

/*
 * Copyright (c) 2007 NTT DATA Corporation
 *
 * 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 jp.terasoluna.fw.message;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.AbstractMessageSource;

/**
 * DAO???????
 * ?????????
 * 
 * <p>
 * ??DB???DB??
 * ???????
 * ????????????
 * ????
 * </p>
 * <strong></strong><br>
 * ??????MessageSource
 * ??????????DB???
 * DAO???????<br>
 * <br>
 * <strong></strong><br>
 * Bean????<br>
 * DAO???DBMessageResourceDAO???<br>
 * 
 * <pre>
 * &lt;bean id = &quot;messageSource&quot;
 *   class = &quot;jp.terasoluna.fw.message.DataSourceMessageSource&quot;&gt;
 *   &lt;property name = &quot;DBMessageResourceDAO&quot;&gt;
 *     &lt;ref bean = &quot;dBMessageResourceDAO&quot;&gt;&lt;/ref&gt;
 *   &lt;/property&gt;
 * &lt;/bean&gt;
 * </pre>
 * 
 * <strong></strong><br>
 * &lt;bean&gt;??id?"messageSource" ????MessageSource
 * ?????<br>
 * &lt;bean>?&lt;property&gt;???DAO??<br>
 * <br>
 * 
 * <br>
 * ?<br>
 * ???????????
 * ????????????????????
 * ??<br>
 * ?????VM????
 * <br>
 * ?????setDefaultLocale?
 * ???????? <br>
 * <br>
 * <strong></strong><br>
 * Bean????<br>
 * ja?)???<br>
 * <br>
 * 
 * <pre>
 * &lt;bean id = &quot;messageSource&quot;
 *   class = &quot;jp.terasoluna.fw.message.DataSourceMessageSource&quot;&gt;
 *   &lt;property name = &quot;DBMessageResourceDAO&quot;&gt;
 *     &lt;ref bean = &quot;dBMessageResourceDAO&quot;&gt;&lt;/ref&gt;
 *   &lt;/property&gt;
 *   &lt;property name = &quot;defaultLocale&quot;&gt;
 *     &lt;value&gt;ja&lt;/value&gt;
 *   &lt;/property&gt;
 * &lt;/bean&gt;
 * </pre>
 * 
 * <strong></strong><br>
 * &lt;bean&gt;?&lt;properities&gt;??name?defaultLocale??
 * value??????
 * 
 * @see jp.terasoluna.fw.message.DBMessage
 * @see jp.terasoluna.fw.message.DBMessageQuery
 * @see jp.terasoluna.fw.message.DBMessageResourceDAO
 * @see jp.terasoluna.fw.message.DBMessageResourceDAOImpl
 * 
 * 
 */
public class DataSourceMessageSource extends AbstractMessageSource implements InitializingBean {

    /**
     * ??????
     * <br>
     * Map &lt;Code, Map &lt;Locale, MessageFormat&gt;&gt;
     */
    protected final Map<String, Map<Locale, MessageFormat>> cachedMessageFormats = new HashMap<String, Map<Locale, MessageFormat>>();

    /**
     * ??????
     * <br/> Map &lt;Locale, Properties&gt;
     */
    protected Map<Locale, Properties> cachedMergedProperties = new HashMap<Locale, Properties>();

    /**
     * 
     */
    private static Log log = LogFactory.getLog(DataSourceMessageSource.class);

    /**
     * ???????? 
     * ????????? ????
     * ????JVM???????
     */
    protected Locale defaultLocale = new Locale(Locale.getDefault().getLanguage());

    /**
     * ??DAO
     */
    protected DBMessageResourceDAO dbMessageResourceDAO = null;

    /**
     * ???????VM?
     * ??VM????????????
     * 
     * @see #getMessageInternal
     * @see java.util.Locale#getDefault
     * 
     * @param defaultLocale
     *            ?
     */
    public void setDefaultLocale(Locale defaultLocale) {
        this.defaultLocale = defaultLocale;
    }

    /**
     * DBMessageResourceDAO?
     * 
     * @param dbMessageResourceDAO
     *            ????DAO
     */
    public synchronized void setDbMessageResourceDAO(DBMessageResourceDAO dbMessageResourceDAO) {
        this.dbMessageResourceDAO = dbMessageResourceDAO;
    }

    /**
     * Web??<br>
     * ???
     * ?????????
     * 
     * @see #cachedMergedProperties
     * 
     */
    @Override
    public void afterPropertiesSet() {
        if (log.isDebugEnabled()) {
            log.debug("afterPropertiesSet");
        }
        readMessagesFromDataSource();
    }

    /**
     * ?
     * ????????DB??
     * ?DB??????????????
     * ?????
     */
    public synchronized void reloadDataSourceMessage() {
        readMessagesFromDataSource();
    }

    /**
     * DAO??????
     * ???????????
     * ?????????<br>
     * ??????
     * ????
     */
    protected synchronized void readMessagesFromDataSource() {
        if (log.isDebugEnabled()) {
            log.debug("readMessageFromDataSource");
        }
        cachedMergedProperties.clear();
        cachedMessageFormats.clear();
        // DAO???
        List<DBMessage> messages = dbMessageResourceDAO.findDBMessages();
        //??null??????
        //??
        for (DBMessage message : messages) {
            if (message.code != null && message.message != null) {
                mapMessage(message);
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("get MessageResource from DAO.");
        }
    }

    /**
     * ?????
     * ????????
     * 
     * @param message
     *            ???DBMessage
     */
    protected void mapMessage(DBMessage message) {
        // ????
        // ??
        Locale locale = createLocale(message);
        // ??????
        Properties messages = getMessages(locale);
        // ????????
        messages.setProperty(message.getCode(), message.getMessage());
        if (log.isDebugEnabled()) {
            log.debug("add Message[" + message.getMessage() + "] (code[" + message.getCode() + "], locale[" + locale
                    + "])");
        }
    }

    /**
     * Locale??<br>
     * ????Locale??
     * ????????????
     * ???Locale??
     * 
     * @param message 
     * 
     * @return
     *      ??????Locale
     *
     * @throws IllegalArgumentException
     *      ?????
     *      ????????????
     *      ??
     */
    protected Locale createLocale(DBMessage message) {
        if (message.getLanguage() == null) {
            if (defaultLocale != null) {
                return defaultLocale;
            }
            if (log.isErrorEnabled()) {
                log.error("Can't resolve Locale.Define Locale" + " in MessageSource or Defaultlocale.");
            }
            throw new IllegalArgumentException(
                    "Can't resolve Locale." + "Define Locale in MessageSource or Defaultlocale.");
        }
        if (message.getCountry() == null) {
            return new Locale(message.getLanguage());
        }
        if (message.getVariant() == null) {
            return new Locale(message.getLanguage(), message.getCountry());
        }
        return new Locale(message.getLanguage(), message.getCountry(), message.getVariant());
    }

    /**
     * ?????? ???
     * ???????????null????
     * 
     * @param locale
     *            ?
     * 
     * @return ????? ?
     * ???????
     */
    protected Properties getMessages(Locale locale) {
        // ??????? 
        Properties messages = cachedMergedProperties.get(locale);
        // ?????????????
        // ?????cachedMergedProperties???
        if (messages == null) {
            messages = new Properties();
            cachedMergedProperties.put(locale, messages);
        }
        return messages;
    }

    /**
     * ?????????
     * ?????
     * AbstractMessageSource?????
     * 
     * @param code
     *            
     * @param locale
     *            ?
     * 
     * @return 
     */
    @Override
    protected synchronized String resolveCodeWithoutArguments(String code, Locale locale) {
        String msg = internalResolveCodeWithoutArguments(code, locale);
        if (msg == null) {
            if (log.isDebugEnabled()) {
                log.debug("could not resolve [" + code + "] for locale [" + locale + "]");
            }
        }
        return msg;
    }

    /**
     * ??? ?????
     * ?????????????
     * ???
     * ????????????
     * ???
     * 
     * @param code
     *            
     * @param locale
     *            ?
     * 
     * @return 
     */
    protected String internalResolveCodeWithoutArguments(String code, Locale locale) {
        // ????msg???
        String msg = getMessages(locale).getProperty(code);
        // ?????????
        if (msg != null) {
            return msg;
        }
        // ?????????????
        // ???

        // ???
        List<Locale> locales = getAlternativeLocales(locale);
        // ???????????
        // ????
        for (int i = 0; i < locales.size(); i++) {
            msg = getMessages(locales.get(i)).getProperty(code);
            if (msg != null) {
                return msg;
            }
        }
        // ??????????null??
        return null;
    }

    /**
     * ???? ??
     * ????????
     * locale??????
     * locale??????
     * ???????
     * ?????
     * ????
     * 
     * @param locale
     *            
     * 
     * @return ???
     */
    protected List<Locale> getAlternativeLocales(Locale locale) {
        List<Locale> locales = new ArrayList<Locale>();
        // ?????
        if (locale.getVariant().length() > 0) {
            // Locale(language,country,"")
            locales.add(new Locale(locale.getLanguage(), locale.getCountry()));
        }
        // ????
        if (locale.getCountry().length() > 0) {
            // Locale(language,"","")
            locales.add(new Locale(locale.getLanguage()));
        }
        // ?????
        if (defaultLocale != null && !locale.equals(defaultLocale)) {
            if (defaultLocale.getVariant().length() > 0) {
                // Locale(language,country,"")
                locales.add(defaultLocale);
            }
            if (defaultLocale.getCountry().length() > 0) {
                // Locale(language,country,"")
                locales.add(new Locale(defaultLocale.getLanguage(), defaultLocale.getCountry()));
            }
            // ????
            if (defaultLocale.getLanguage().length() > 0) {
                // Locale(language,"","")
                locales.add(new Locale(defaultLocale.getLanguage()));
            }
        }
        return locales;
    }

    /**
     * ???????
     * ????
     * ???AbstractMessageSource?
     * ????
     * 
     * @param code
     *            
     * @param locale
     *            ?
     * 
     * @return 
     */
    @Override
    protected synchronized MessageFormat resolveCode(String code, Locale locale) {
        // ????messageFormat?
        // ??
        MessageFormat messageFormat = getMessageFormat(code, locale);
        // ?????????
        if (messageFormat != null) {
            if (log.isDebugEnabled()) {
                log.debug("resolved [" + code + "] for locale [" + locale + "] => [" + messageFormat + "]");
            }
            return messageFormat;
        }
        // ?????????????
        // ???

        // ???
        List<Locale> locales = getAlternativeLocales(locale);
        // ?????????
        // ??????
        for (int i = 0; i < locales.size(); i++) {
            messageFormat = getMessageFormat(code, locales.get(i));
            if (messageFormat != null) {
                if (log.isDebugEnabled()) {
                    log.debug("resolved [" + code + "] for locale [" + locale + "] => [" + messageFormat + "]");
                }
                return messageFormat;
            }
        }
        if (messageFormat == null) {
            if (log.isDebugEnabled()) {
                log.debug("could not resolve [" + code + "] for locale [" + locale + "]");
            }
        }
        // ?????????null??
        return null;
    }

    /**
     * ???????
     * ?
     * 
     * @param code
     *            
     * @param locale
     *            ?
     * 
     * @return ??
     */
    protected MessageFormat getMessageFormat(String code, Locale locale) {
        // ?????
        Map<Locale, MessageFormat> localeMap = this.cachedMessageFormats.get(code);
        // ???????
        // ????
        if (localeMap != null) {
            MessageFormat result = localeMap.get(locale);
            if (result != null) {
                return result;
            }
        }

        String msg = getMessages(locale).getProperty(code);

        // ???
        if (msg != null) {

            // ???????????
            // ??
            if (localeMap == null) {
                localeMap = new HashMap<Locale, MessageFormat>();
                this.cachedMessageFormats.put(code, localeMap);
            }
            // ???
            MessageFormat result = createMessageFormat(msg, locale);
            localeMap.put(locale, result);
            return result;
        }
        // ?????????null??
        return null;
    }
}