Java tutorial
/* * 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 * <message-resources>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) * <message-resource>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> * <struts-config> * ?c * <message-resources parameter="MessageResources" * factory="jp.terasoluna.fw.web.struts.action.DBMessageResourcesFactory" * /> * ?c * </struts-config> * </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=<SQL(SELECT)> * 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> * <?bZ?[WL?[>=<?bZ?[W> * </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); } }