S-JIS[2009-09-23] 変更履歴

メッセージクラス自動生成ツール

for JDK1.5 by Excel2003

ひしだま作の、Excelに記述したメッセージ一覧からJavaの定数クラス及び文言のプロパティーファイルを自動生成するツールです。

msgcode.zip (30.9kB) [2009-09-23]

メッセージコードの仕様(形式や連番の桁数とか)はシステムによって異なるので、カスタマイズするのが前提です。


使用例

Excelの記述例

  A B C D E F G
1              
2
レベル

コード

概要

テキスト
可変部の説明  
3 0 1  
4 I 0001 サンプル サンプルメッセージ:{0} 自由文言    
5 I 0002 処理開始 {0}処理開始 処理名    
6 I 0003 処理終了 {0}処理終了:コード={1} 処理名 終了コード  
7 W 0001 警告終了 警告終了      
8 E 0001 異常終了 異常終了:コード={0} 異常コード    
9              

生成されるクラスのイメージ

/**
 * メッセージコード定数.
 */
public enum MsgCodeEnum {

	/** サンプル */
	MSGCODE_I_0001(Level.INFO),
	/** 処理開始 */
	MSGCODE_I_0002(Level.INFO),
	/** 処理終了 */
	MSGCODE_I_0003(Level.INFO),
	/** 警告終了 */
	MSGCODE_W_0001(Level.WARNING),
	/** 異常終了 */
	MSGCODE_E_0001(Level.SEVERE),
	;

	protected Level level;

	/**
	 * コンストラクター.
	 *
	 * @param level メッセージレベル
	 */
	MsgCodeEnum(Level level) {
		this.level = level;
	}

	/**
	 * メッセージレベル取得.
	 *
	 * @return メッセージレベル
	 */
	public Level getLevel() {
		return level;
	}

	protected static ResourceBundle RESOURCE_BUNDLE;

	/**
	 * メッセージテキスト取得.
	 *
	 * @return メッセージテキスト
	 */
	public String getText() {	//TODO synchronizedした方がいいか?
		if (RESOURCE_BUNDLE == null) {
			RESOURCE_BUNDLE = ResourceBundle.getBundle(MsgCodeEnum.class.getPackage().getName() + ".msgcode_text");
		}
		return RESOURCE_BUNDLE.getString(name());
	}
}

生成されるプロパティーファイルのイメージ

##############################
# メッセージコード文言
# (日本語用)
##############################

#サンプル
MSGCODE_I_0001=サンプルメッセージ:{0}
#処理開始
MSGCODE_I_0002={0}処理開始
#処理終了
MSGCODE_I_0003={0}処理終了:コード={1}
#警告終了
MSGCODE_W_0001=警告終了
#異常終了
MSGCODE_E_0001=異常終了:コード={0}

#END

メッセージを使用する例

import jp.hishidama.msgcode.excel.Message;
import static jp.hishidama.msgcode.excel.MsgCodeEnum.*;
	Message m = MSGCODE_I_0001.createMessage("引数の例");
	Message e = MSGCODE_I_0003.createMessage("サンプル", Integer.toString(123));

	String text = m.getText();

補記

メッセージコードを表すクラスは、ここではあえて列挙型(enum)を使っています。

昔からよくあるコーディングでは、この手のメッセージコードはString型で記述されることが多いような気がします。
しかも下手をすると、定数クラスにすらなっていない!

//メッセージコードを直書きする駄目な例
	Message m = MessageCodeManager.getMessage("I_0001");
	Message m = MessageCodeManager.getMessage("I_0009"); ←存在しない値を書いても実行するまで発覚しない

文字列で直書きすると、存在しないコードを使ってもコンパイルエラーになりません。
また、あるコードを使っている箇所を検索しようとした場合、別の文字列が一部だけマッチして引っかかってくる可能性があります。
最低限、定数フィールド化(static finalなフィールドにする)は必須でしょう。

public interface MsgCodeConstant {

	/** サンプル */
	public static final String MSGCODE_I_0001 = "I_0001";
	/** 処理開始 */
	public static final String MSGCODE_I_0002 = "I_0002";
	/** 処理終了 */
	public static final String MSGCODE_I_0003 = "I_0003";
	/** 警告終了 */
	public static final String MSGCODE_W_0001 = "W_0001";
	/** 異常終了 */
	public static final String MSGCODE_E_0001 = "E_0001";
}

	Message m = MessageCodeManager.getMessage(MsgCodeConstant.MSGCODE_I_0009);	←存在しないのでコンパイルエラー

しかしこういった個数の限られた値群にこそ、列挙型を使用すべきだと思います。
Stringでは、結局、他の全然関係ない値を指定することが許されてしまうからです。

	Message m = MessageCodeManager.getMessage("zzz"); ←存在しない値を書いても実行するまで発覚しない

そして、これらを手でいちいちコーディングするのは馬鹿らしいし、どうせメッセージ一覧はExcelで管理することがほとんどだから、Excelマクロ(VBA)で自動生成するのが自然の流れでしょう。
(また、Excelで管理していても、“設計書としての体裁を優先して、マクロで自動生成できない”ようなものは工数の無駄だと思う)


個人的には、文言を管理する為にプロパティーファイルやXMLファイルを使うのも嫌いです。
仮にプロパティーファイル内に存在しないキーをJavaプログラムで使ってしまった場合、それを実行するまで問題が発覚しないからです。
(また、Eclipse上でのF3キーを使った移動も出来ないから)
まぁExcelから自動生成してその定数を使っていれば、プロパティーファイルとの不整合は起きないはずですが。

列挙型を使えば、コード値のクラスにメソッドを追加できる為、文言だって指定するのは簡単です。

public enum MstCodeEnum {

	/** サンプル */
	MSGCODE_I_0001(Level.INFO, "サンプルメッセージ:{0}"),
	/** 処理開始 */
	MSGCODE_I_0002(Level.INFO, "{0}処理開始"),
	/** 処理終了 */
	MSGCODE_I_0003(Level.INFO, "{0}処理終了:コード={1}"),
	/** 警告終了 */
	MSGCODE_W_0001(Level.WARNING, "警告終了"),
	/** 異常終了 */
	MSGCODE_E_0001(Level.SEVERE, "異常終了:コード={0}"),
	;
〜
}

とは言うものの、多言語対応を考えれば、ResourceBundleというクラスがそれに対応している訳だし、その仕組みを使うのがきっと無難でしょう。


自作ソフトへ戻る / 技術メモへ行く
メールの送信先:ひしだま