jp.terasoluna.fw.web.struts.action.DBMessageResources.java Source code

Java tutorial

Introduction

Here is the source code for jp.terasoluna.fw.web.struts.action.DBMessageResources.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.web.struts.action;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import jp.terasoluna.fw.exception.SystemException;
import jp.terasoluna.fw.util.ClassLoadException;
import jp.terasoluna.fw.util.ClassUtil;
import jp.terasoluna.fw.util.PropertyUtil;
import jp.terasoluna.fw.web.struts.MessageFormatCacheMapFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.MessageResourcesFactory;

/**
 * <h3>
 * ?bZ?[W\?[XNX.
 * </h3>
 *
 * <p>
 * ?bZ?[W\?[X@\?AJSP\G?[?bZ?[W?A
 * L?[?bZ?[W@\?B<br>
 * NXgp?A?bZ?[W\?[X`t@C
 * ?i?Strutsgv?peBt@C`?bZ?[W\?[X?j?A
 * NX??[hDBQ??ADB?bZ?[W\?[Xgp
 * \?B
 * </p>
 * <p>
 * NX?A
 * Won't FixStrutsoO STR-2172(https://issues.apache.org/jira/browse/STR-2172)
 * iL?B<br>
 * ???A{@link MessageFormatCacheMapFactory} Q??B
 * </p>
 *
 * <h5>Tvp?</h5>
 *
 * <p>
 * DB??bZ?[W\?[X?ASW?[
 * L?A?bZ?[W\?[X`t@C?bZ?[W\?[X?A
 * StrutseW?[?B
 * Tvp?ANXgp?A?bZ?[W\?[X@\
 * ?U??B
 * </p>
 *
 * <h6>Tv?</h6>
 * <p>
 * ?AW?[A?AW?[B?W?[??A
 * W?[?bZ?[W\?[X??i?bZ?[W\?[X`t@C?j
 * Lw?B<br>
 * <br>
 * <table border="1">
 *   <caption>?bZ?[W\?[X</caption>
 *   <tr>
 *     <td>W?[</td>
 *     <td>?bZ?[WL?[</td>
 *     <td>?bZ?[W</td>
 *     <td>?bZ?[Wo^?</td>
 *   </tr>
 *   <tr>
 *     <td rowspan="2">W?[A</td>
 *     <td>message.propMessageResource</td>
 *     <td>"moduleA"</td>
 *     <td>?bZ?[W\?[X`t@C</td>
 *   </tr>
 *   <tr>
 *     <td>message.dbMessageResource</td>
 *     <td>"DB"</td>
 *     <td>DB</td>
 *   </tr>
 *   <tr>
 *     <td rowspan="2">W?[B</td>
 *     <td>message.propMessageResource</td>
 *     <td>"moduleB"</td>
 *     <td>?bZ?[W\?[X`t@C</td>
 *   </tr>
 *   <tr>
 *     <td>message.subMessageResource</td>
 *     <td>"subModule"</td>
 *     <td>?bZ?[W\?[X`t@C</td>
 *   </tr>
 * </table>
 * </p>
 *
 * <h6>W?[?bZ?[W\?[X</h6>
 * ?\?AW?[A?bZ?[W\?[X?A
 * <ul>
 *   <li>W?[A`?bZ?[W\?[X`t@C
 *       <code>message.propMessageResource</code>
 *   </li>
 *   <li>DB?bZ?[W\?[X<code>message.dbMessageResource</code>
 *   </li>
 * </ul>
 * ?B<br>
 * W?[B?bZ?[W\?[X?A
 * <ul>
 *   <li>W?[B`?bZ?[W\?[X`t@C
 *       <code>message.propMessageResource</code></li>
 *   <li>W?[B`?bZ?[W\?[X`t@C
 *       <code>message.subMessageResource</code></li>
 *   <li>W?[ADB?bZ?[W\?[X
 *       <code>message.dbMessageResource</code></li>
 * </ul>
 * ?B<br>
 * W?[AW?[B?A?bZ?[W\?[XL?[
 * <code>message.propMessageResource</code>?AeW?[
 * ?bZ?[W?A
 * <ul>
 *   <li>W?[A"moduleA"</li>
 *   <li>W?[B"moduleB"</li>
 * </ul>
 * ?B
 * ?bZ?[W\?[X`t@C?bZ?[W\?[X??A
 * eW?[?L??B<br>
 * ?AW?[LDB?bZ?[W\?[X?A
 * <code>message.dbMessageResource</code>?bZ?[W?A
 * W?[A?AW?[B "DB"?B<br>
 * ?AStrutsdl?AW?[B?bZ?[W\?[X`t@C
 * ??bZ?[W\?[XW?[A?B
 * ?iW?[A<code>module.subMessageResource</code>L?[
 * Q??A?bZ?[W?B?j
 * <h6>?_</h6>
 * ?A?bZ?[W\?[XL?_?B
 * <ul>
 *   <li>?bZ?[W\?[X`t@C`?bZ?[W
 *       ???A?bZ?[WL?[`?A
 *       ?W?[?AgpW?[
 *       l</li>
 *   <li>DB?bZ?[W\?[X????AW?[
 *       Q?\</li>
 *   <li>DB?bZ?[W\?[X?bZ?[W\?[X`t@C
 *       ?bZ?[W\?[XL?[?A?bZ?[W\?[X`t@C
 *       ?bZ?[W</li>
 *   <li>DBMessageResourcesp???A????B
 *       DB?bZ?[W\?[X?A?bZ?[W\?[X`
 *       t@C?P?[?p?A?B<br>
 *       ???sKv???Astruts-config.xml
 *       &lt;message-resources&gt;vffactory??AStruts
 *       PropertyMessageResourcesFactoryTERASOLUNA
 *       PropertyMessageResourcesExFactorypKv?B
 *       ?A??DB?bZ?[W\?[X?B</li>
 * </ul>
 * ?APL?[?ADBMessageResources?bZ?[WD???A
 * L?B<br>
 * <ol>
 *   <li>?bZ?[W\?[X`t@C`?bZ?[W\?[X</li>
 *   <li>DB`?bZ?[W\?[X</li>
 *   <li>?bZ?[W\?[X`t@C
 *       ?iapplication-messages.properties?j
 *       `?bZ?[W\?[X</li>
 *   <li>VXe?bZ?[W\?[X`t@C
 *       ?isystem-messages.properties?j
 *       `?bZ?[W\?[X</li>
 * </ol>
 * ?bZ?[W\?[X?EVXe?bZ?[W\?[Xe?A
 * {@link GlobalMessageResources}Q??B
 *
 * <br><br>
 *
 * <h5>gp@</h5>
 * NXp?AStruts?t@C(struts-config.xml)
 * &lt;message-resource&gt;vf?A
 * <ul>
 *   <li>parameter??bZ?[W\?[X`t@C
 *       gq(<code>.properties</code>)?</li>
 *   <li>factory??A<code>DBMessageResourcesFactory</code></li>
 * </ul>
 * w?B
 *
 * <fieldset style="border:1pt solid black;padding:10px;width:100%;">
 * <legend>LStruts?t@C(struts-config.xml)??B</legend>
 * <code><pre>
 * &lt;struts-config&gt;
 *   ?c
 *   &lt;message-resources parameter="MessageResources"
 *                      factory="jp.terasoluna.fw.web.struts.action.DBMessageResourcesFactory"
 *   /&gt;
 *   ?c
 * &lt;/struts-config&gt;
 * </pre></code>
 * </fieldset>
 *
 * <br>
 *
 * <fieldset style="border:1pt solid black;padding:10px;width:100%;">
 * <legend><h5>DB?bZ?[W\?[X?</h5></legend>
 * DB?bZ?[W\?[X?AVXe?v?peBt@C
 * ?isystem.properties?j?AL??B
 * <fieldset style="border:1pt solid black;padding:10px;width:100%;">
 * <pre><code>
 * messages.sql=&lt;SQL(SELECT)&gt;
 * messages.dao=MessageResourcesDAONX
 * </code></pre>
 * </fieldset>
 * <br>
 *
 * ?B
 * <fieldset style="border:1pt solid black;padding:10px;width:100%;">
 * <pre><code>
 * messages.sql=SELECT MESSAGE_KEY, MESSAGE_VALUE FROM MESSAGES
 * messages.dao=jp.terasoluna.fw.web.struts.action.MessageResourcesDAOImpl
 * </code></pre>
 * </fieldset>
 * </fieldset>
 *
 * <h6>???_</h6>
 * <ul>
 *  <li>?SQL?APJ?i?L?MESSAGE_KEY?j?bZ?[WL?[
 *      ??AQJ?iMESSAGE_VALUE?j?bZ?[Wi[
 *      Zbg?B</li>
 *  <li>?DAO?AMessageResourcesDAONX?A
 *      ?RXgN^?NX?B
 *      TERASOLUNAMessageResourcesDAOImplC^tF?[X
 *      ?A?RXgN^?B
 *      <strong>{@link MessageResourcesDAOImpl}gp@
 *      NXJavadocQ??B</strong></li>
 * </ul>
 *
 * <fieldset style="border:1pt solid black;padding:10px;width:100%;">
 * <legend><h5>?bZ?[W\?[X`t@C?iv?peBt@C?j
 *     ?bZ?[W\?[X?</h5></legend>
 * v?peBt@Cp?bZ?[W\?[X`?Av?peBt@C
 * `o^?B
 * <fieldset style="border:1pt solid black;padding:10px;width:100%;">
 * <pre><code>
 * &lt;?bZ?[WL?[&gt;=&lt;?bZ?[W&gt;
 * </code></pre>
 * </fieldset>
 * <br>
 * ?B
 * <fieldset style="border:1pt solid black;padding:10px;width:100%;">
 * <pre><code>
 * errors.requiredArray={0}{1}K?{?B
 * errors.alphaNumericStringArray={0}{1}pp??B
 * </code></pre>
 * </fieldset>
 * </fieldset>
 * <br>
 *
 * @see jp.terasoluna.fw.web.struts.MessageFormatCacheMapFactory
 * @see jp.terasoluna.fw.web.struts.action.GlobalMessageResources
 * @see jp.terasoluna.fw.web.struts.action.DBMessageResourcesFactory
 * @see jp.terasoluna.fw.web.struts.action.MessageResourcesDAO
 * @see jp.terasoluna.fw.web.struts.action.MessageResourcesDAOImpl
 *
 */
public class DBMessageResources extends MessageResources {

    /**
     * VAo?[WID
     */
    private static final long serialVersionUID = 8244415315747028752L;

    /**
     * VXe?v?peBt@C?isystem.properties?j
     * DAO?gpL?[?B
     */
    public static final String MESSAGES_DAO = "messages.dao";

    /**
     * VXe?v?peBt@C?isystem.properties?j
     * SQL?gpL?[?B
     */
    public static final String MESSAGES_SQL = "messages.sql";

    /**
     *  ?bZ?[Ws\G?[R?[h?B
     */
    private static final String DB_MESSAGE_RESOURCES_ERROR = "errors.db.message.resources";

    /**
     *  ?bZ?[W\?[X?s\G?[R?[h?B
     */
    private static final String DB_MESSAGE_RESOURCES_ERROR_INIT = "errors.db.message.resources.init";

    /**
     * ?ONX?B
     */
    @SuppressWarnings("hiding")
    private static Log log = LogFactory.getLog(DBMessageResources.class);

    /**
     * DB?bZ?[WL?[?bZ?[Wi[Map?B
     * NXL?B
     */
    private static Map dbMessages = null;

    /**
     * ?bZ?[W\?[X`t@C?bZ?[WL?[
     * ?bZ?[Wi[Map?B
     * 
     * DB?bZ?[W\?[X?AStrutsW?[P
     * ?B
     */
    private Map<String, String> messages = new HashMap<String, String>();

    /**
     * wp??[^DBMessageResources???B
     *
     * @param factory ?bZ?[W\?[Xt@Ng
     * @param config ?bZ?[W\?[X`t@C
     */
    public DBMessageResources(MessageResourcesFactory factory, String config) {
        super(factory, config);
        if (log.isDebugEnabled()) {
            log.debug("call DBMessageResources()");
        }
        replaceMessageFormatCache();
        // DB?bZ?[W\?[X??ADB?bZ?[W\?[X?B
        if (dbMessages == null) {
            dbInit();
        }
        propertyInit(config);
    }

    /**
     * wp??[^DBMessageResources???B
     * 
     * @param factory ?bZ?[W\?[Xt@Ng
     * @param config ?bZ?[W\?[X`t@C
     * @param returnNull <code>org.apache.struts.util.MessageResources</code>
     *                   NX <code>returnNull</code>
     *                   <code>false</code> w?AL?[Y?bZ?[W
     *                   ??????Locale.key???`?bZ?[W
     *                   p?B
     */
    public DBMessageResources(MessageResourcesFactory factory, String config, boolean returnNull) {
        super(factory, config, returnNull);
        if (log.isDebugEnabled()) {
            log.debug("call DBMessageResources()");
        }
        replaceMessageFormatCache();
        // DB?bZ?[W\?[X??ADB?bZ?[W\?[X?B
        if (dbMessages == null) {
            dbInit();
        }
        propertyInit(config);
    }

    /**
     * MessageFormatLbV(formats)CX^X??s?B
     * <p>
     * StrutsoO STR-2172pLbVIuWFNg??B
     * </p>
     * @see MessageFormatCacheMapFactory
     */
    private void replaceMessageFormatCache() {
        HashMap<String, MessageFormat> map = MessageFormatCacheMapFactory.getInstance();
        if (map != null) {
            formats = map;
        }
    }

    /**
     * DB?bZ?[WL?[?bZ?[WyA?B
     */
    protected static void dbInit() {

        if (log.isDebugEnabled()) {
            log.debug("call dbInit()");
        }

        // xdbMessagesMap?
        dbMessages = new HashMap();

        // VXe?v?peBt@C?isystem.properties?jv?peB
        // 
        String daoName = PropertyUtil.getProperty(MESSAGES_DAO);
        String sql = PropertyUtil.getProperty(MESSAGES_SQL);
        if (daoName == null && sql == null) {
            // L?[`?I
            return;
        } else if (daoName == null || sql == null) {
            // `??x???O?o?A?I
            if (log.isWarnEnabled()) {
                log.warn("defined only one of the pair - " + MESSAGES_DAO + " and " + MESSAGES_SQL + ".");
            }
            return;
        }

        // DAOCX^X??
        MessageResourcesDAO dao = null;
        try {
            dao = (MessageResourcesDAO) ClassUtil.create(daoName);
        } catch (ClassLoadException e) {
            // `NX??[h??
            log.error("\"" + daoName + "\" cannot loaded.", e);
            throw new SystemException(e, DB_MESSAGE_RESOURCES_ERROR_INIT);
        } catch (ClassCastException e) {
            // `NXMessageResourcesDAO??
            log.error("\"" + daoName + "\" not implemented" + " MessageResourcesDAO", e);
            throw new SystemException(e, DB_MESSAGE_RESOURCES_ERROR_INIT);
        }

        // MessagelMap?B
        dbMessages = dao.queryMessageMap(sql);

    }

    /**
     *  ?bZ?[W\?[X`t@C?bZ?[WL?[?bZ?[W
     *  yA?B
     *
     * @param propertyFile ?bZ?[W\?[X`t@C
     */
    protected void propertyInit(String propertyFile) {
        Properties props = null;
        Iterator names = null;

        if (log.isDebugEnabled()) {
            log.debug("call propertyInit()");
        }

        // ?bZ?[W\?[X`t@C??[h
        props = PropertyUtil.loadProperties(propertyFile);
        if (props == null) {
            log.error("Message resources file \"" + propertyFile + "\" is illegal.");
            return;
        }
        // nbV}bvl?s
        names = props.keySet().iterator();
        while (names.hasNext()) {
            String key = (String) names.next();
            if (log.isDebugEnabled()) {
                log.debug("Saving property message key [" + key + "]" + "value [" + props.getProperty(key) + "]");
            }
            messages.put(key, props.getProperty(key));
        }
    }

    /**
     * wL?[?bZ?[W?B
     * L?[?bZ?[W`????AD??
     * L?B
     * <ol>
     *  <li>?bZ?[W\?[X`t@C?bZ?[W\?[X</li>
     *  <li>DB?bZ?[WL?[?bZ?[W?bZ?[W\?[X
     *      </li>
     *  <li>?bZ?[W\?[Xt@C`t@C
     *      ?iapplication-messages.properties?j?bZ?[W\?[X</li>
     *  <li>VXe?bZ?[W\?[X`t@C?isystem-messages.properties?j
     *      ?bZ?[W\?[X</li>
     * </ol>
     * <p>
     *  ?bZ?[W\?[X????s???A
     *  ?A`?bZ?[WL?[Yl
     *  ???A??returnNullw?A
     *  null?AStruts`?i???Locale.key????jp?B
     * </p>
     * <p>
     *  ?Aw?P?[?l?B
     *  getMessage(key)??B
     * </p>
     *
     * @param locale ?bZ?[W?P?[?B?l
     * @param key ?bZ?[WL?[
     * 
     * @return localekey?bZ?[W
     */
    @Override
    public String getMessage(Locale locale, String key) {
        MessageResources globalMessageResources = null;

        if (log.isDebugEnabled()) {
            log.debug("call getMessage(Locale, String)");
        }

        if (key == null || "".equals(key)) {
            log.error("Message key 'null' or empty not allowed.");
            throw new SystemException(null, DB_MESSAGE_RESOURCES_ERROR);
        }

        // ?bZ?[W\?[X`t@C?bZ?[W
        if (messages != null) {
            String retMessage = messages.get(key);
            if (retMessage != null) {
                return retMessage;
            }
        }

        // DB?bZ?[W
        if (dbMessages != null) {
            String retMessage = (String) dbMessages.get(key);
            if (retMessage != null) {
                return retMessage;
            }
        }

        // ?EVXe?bZ?[W
        globalMessageResources = GlobalMessageResources.getInstance();
        String retMessage = globalMessageResources.getMessage(locale, key);
        if (retMessage != null) {
            return retMessage;
        }

        // ??returnNull?L
        if (!returnNull) {
            return "???" + messageKey(locale, key) + "???";
        }
        return null;
    }

    /**
     * wL?[?bZ?[W?B
     * L?[?bZ?[W`????AD??
     * L?B
     * <ol>
     *  <li>?bZ?[W\?[X`t@C</li>
     *  <li>DB?bZ?[WL?[?bZ?[We?[u</li>
     *  <li>?bZ?[W\?[Xt@C`t@C
     *      ?iapplication-messages.properties?j?bZ?[W</li>
     *  <li>VXe?bZ?[W\?[X`t@C?isystem-messages.properties?j
     *      ?bZ?[W</li>
     * </ol>
     *  ?bZ?[W\?[X????s???A
     *  ?A`?bZ?[WL?[Yl
     *  ???Anullp?B
     *
     * @param key ?bZ?[WL?[
     * 
     * @return key?bZ?[W
     */
    @Override
    public String getMessage(String key) {
        Locale locale = null;
        return getMessage(locale, key);
    }

}