4 * License : The MIT License
5 * Copyright(c) 2012 olyutorskii
8 package jp.sfjp.jindolf;
10 import java.awt.Frame;
11 import java.awt.GraphicsEnvironment;
12 import java.io.PrintStream;
13 import java.text.MessageFormat;
14 import java.util.concurrent.atomic.AtomicBoolean;
15 import javax.swing.JOptionPane;
18 * JRE1.7の利用が解禁されたJindolfエントリ。
20 * <p>起動クラスJindolfの下請けとしての機能が想定される。
22 * <p>必ずしも必要ないが、異常系切り分けに有用な、
23 * 実行環境やビルドの成否に関する各種診断を行う。
25 * <p>各種診断を通過した後、JindolfMainに制御を渡す。
27 public final class JindolfJre17 {
29 /** GUI環境に接続できないときの終了コード。 */
30 public static final int EXIT_CODE_HEADLESS = 1;
31 /** アプリのビルド工程の不備を自動検出した時の終了コード。 */
32 public static final int EXIT_CODE_BUILDMISS = 1;
33 /** VM内多重起動を自動検出した時の終了コード。 */
34 public static final int EXIT_CODE_INVOKEDBL = 1;
36 private static final PrintStream STDERR = System.err;
38 private static final String ERRMSG_GUISESS =
39 "ERROR : GUI session failed.";
40 private static final String ERRMSG_DISPLAY =
41 "{0}\nEnvironment: DISPLAY [{1}]";
43 private static final String TITLE_SRCENC = "Build failed";
44 private static final String ERRMSG_SRCENC =
45 "ERROR : Invalid source-code encoding detected.\n"
46 + "Let's check encoding with compiler & source-file.";
48 private static final String TITLE_PKGERR = "ビルドエラー";
49 private static final String ERRMSG_PKG =
50 "パッケージ定義と{0}が一致しません。[{1}]≠[{2}]";
52 private static final String TITLE_INVOKEDBL = "多重起動";
53 private static final String ERRMSG_INVOKEDBL =
54 "ERROR : 二度目以降の起動がキャンセルされました。";
56 private static final char[][] ENCODING_TEST = {
58 {' ', 0x3000}, // 全角スペース
59 {'\\', 0x005c}, // バックスラッシュ
60 {'¥', 0x00a5}, // 半角円通貨
62 {'~', 0xff5e}, // 全角チルダ
63 {'〜', 0x301c}, // 波ダッシュ
64 {'�', 0xfffd}, // Unicode専用特殊文字
68 private static final AtomicBoolean INVOKE_FLAG =
69 new AtomicBoolean(false);
75 private JindolfJre17(){
82 * GUI環境に接続できなければJVMを終了させる。
83 * @return 成功すれば0。失敗したら0以外。
85 private static int proveGuiEnv(){
86 if( ! GraphicsEnvironment.isHeadless() ) return 0;
88 String errMsg = ERRMSG_GUISESS;
92 dispEnv = System.getenv("DISPLAY"); // for X11
93 }catch(SecurityException e){
98 errMsg = MessageFormat.format(ERRMSG_DISPLAY, errMsg, dispEnv);
101 STDERR.println(errMsg);
104 return EXIT_CODE_HEADLESS;
109 * @param errmsg エラーメッセージ
112 private static void showErrorDialog(String errmsg, String title){
114 JOptionPane.showMessageDialog(parent,
117 JOptionPane.ERROR_MESSAGE);
122 * ビルド時のエンコーディングミスを判定する。
124 * <p>※ 非Unicode系の開発環境を使いたい人は適当に無視してね。
126 * @return 成功すれば0。失敗したら0以外。
128 private static int checkSourceEncoding(){
130 for(char[] pair : ENCODING_TEST){
131 char compiled = pair[0];
132 char expected = pair[1];
133 if(compiled != expected){
140 String errmsg = ERRMSG_SRCENC;
142 showErrorDialog(errmsg, TITLE_SRCENC);
144 return EXIT_CODE_BUILDMISS;
148 * MANIFEST.MFパッケージ定義エラーの検出。
149 * @return 成功すれば0。失敗したら0以外。
151 private static int checkPackageDefinition(){
152 Package rootPkg = ResourceManager.DEF_ROOT_PACKAGE;
153 String implTitle = rootPkg.getImplementationTitle();
154 String implVersion = rootPkg.getImplementationVersion();
155 String implVendor = rootPkg.getImplementationVendor();
157 String title = TITLE_PKGERR;
159 if(implTitle != null && ! VerInfo.TITLE.equals(implTitle) ){
160 String errmsg = MessageFormat.format(
161 ERRMSG_PKG, "タイトル", implTitle, VerInfo.TITLE );
162 showErrorDialog(errmsg, title);
163 return EXIT_CODE_BUILDMISS;
166 if(implVersion != null && ! VerInfo.VERSION.equals(implVersion) ){
167 String errmsg = MessageFormat.format(
169 "バージョン番号", implVersion, VerInfo.VERSION );
170 showErrorDialog(errmsg, title);
171 return EXIT_CODE_BUILDMISS;
174 if(implVendor != null && ! VerInfo.AUTHOR.equals(implVendor) ){
175 String errmsg = MessageFormat.format(
176 ERRMSG_PKG, "ベンダ", implVendor, VerInfo.AUTHOR );
177 showErrorDialog(errmsg, title);
178 return EXIT_CODE_BUILDMISS;
185 * JVM内で多重起動していないかチェックする。
187 * <p>多重起動を確認した場合は、GUIにダイアログを出力する。
189 * @return 成功すれば0。失敗したら0以外。
191 private static int checkHasInvoked(){
192 boolean successed = INVOKE_FLAG.compareAndSet(false, true);
193 if(successed) return 0;
195 showErrorDialog(ERRMSG_INVOKEDBL, TITLE_INVOKEDBL);
197 return EXIT_CODE_INVOKEDBL;
201 * Jindolf のスタートアップエントリ。
203 * <p>ここからJRE1.7の利用が解禁される。
205 * <p>最終的に{@link JindolfMain}へ制御が渡される。
207 * @param args コマンドライン引数
208 * @return 起動に成功すれば0。失敗したら0以外。
210 public static int main(String... args){
213 exitCode = proveGuiEnv();
214 if(exitCode != 0) return exitCode;
215 // ここから異常系でのみSwingGUI解禁
217 exitCode = checkSourceEncoding();
218 if(exitCode != 0) return exitCode;
219 // ここから日本語を含むUnicode出力解禁。
221 exitCode = checkPackageDefinition();
222 if(exitCode != 0) return exitCode;
224 exitCode = checkHasInvoked();
225 if(exitCode != 0) return exitCode;
227 exitCode = JindolfMain.main(args);