OSDN Git Service

4a419e2e4b898adbf840a645bbe3a8dc1206d519
[charactermanaj/CharacterManaJ.git] / src / main / java / charactermanaj / util / ConfigurationDirUtilities.java
1 package charactermanaj.util;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.net.URL;
6 import java.security.CodeSource;
7 import java.security.ProtectionDomain;
8 import java.util.logging.Level;
9 import java.util.logging.Logger;
10
11 import charactermanaj.Main;
12
13 /**
14  * アプリケーションの設定ファイル等の位置を取得するユーテリティクラス.<br>
15  * Mainクラスのロード時に最も早くロードされるであろうクラスの一つである.<br>
16  * @author seraphy
17  */
18 public final class ConfigurationDirUtilities {
19
20         public static final String CONFIGURATION_DIR_NAME = "CharacterManaJ";
21
22         private static File userDataDir;
23         
24         private static File applicationBaseDir;
25         
26         private ConfigurationDirUtilities() {
27                 throw new RuntimeException("utilities class.");
28         }
29         
30         /**
31          * ユーザーごとのアプリケーションデータ保存先を取得する.<br>
32          * 環境変数「APPDATA」もしくはシステムプロパティ「appdata.dir」からベース位置を取得する.<br>
33          * いずれも設定されておらず、Mac OS Xであれば「~/Library」をベース位置とする。
34          * Mac OS Xでなければ「~/」をベース位置とする.<br>
35          * これに対してシステムプロパティ「characterdata.dirname」(デフォルトは「CharacterManaJ」)という
36          * フォルダをユーザー毎のアプリケーションデータの保存先ディレクトリとする.<br>
37          */
38         public synchronized static File getUserDataDir() {
39                 if (userDataDir == null) {
40                         
41                         String appData = null;
42                         // システムプロパティ「appdata.dir」を探す
43                         appData = System.getProperty("appdata.dir");
44                         if (appData == null) {
45                                 // なければ環境変数APPDATAを探す
46                                 // Windows2000/XP/Vista/Windows7には存在する.
47                                 appData = System.getenv("APPDATA");
48                         }
49                         if (appData == null && Main.isMacOSX()) {
50                                 // システムプロパティも環境変数にも設定がなく、実行環境がMac OS Xであれば
51                                 // ~/Libraryをベースにする.(Mac OS Xならば必ずある。)
52                                 appData = new File(System.getProperty("user.home"), "Library").getPath();
53                         }
54                         if (appData == null) {
55                                 // なければシステムプロパティ「user.home」を使う
56                                 // このプロパティは必ず存在する.
57                                 appData = System.getProperty("user.home");
58                         }
59
60                         // システムプロパティ「characterdata.dirname」のディレクトリ名、なければ「CharacterManaJ」を設定する.
61                         String characterDirName = System.getProperty("characterdata.dirname", CONFIGURATION_DIR_NAME);
62                         userDataDir = new File(appData, characterDirName).getAbsoluteFile();
63
64                         // ディレクトリを準備する.
65                         if (!userDataDir.exists()) {
66                                 if (!userDataDir.mkdirs()) {
67                                         // ログ保管場所も設定されていないのでコンソールに出すしかない.
68                                         System.err.println("can't create the user data directory. " + userDataDir);
69                                 }
70                         }
71                 }
72                 return userDataDir;
73         }
74
75         /**
76          * アプリケーションディレクトリを取得する.<br>
77          * このクラスをコードソースから、ベースとなる位置を割り出す.<br>
78          * クラスが格納されているクラスパスのフォルダか、JARに固められている場合は、そのJARファイルの、その親ディレクトリを指し示す.<br>
79          * このクラスのプロテクションドメインのコードソースがnullでコードの位置が取得できないか、
80          * コードの位置を示すURLがファイルプロトコルでない場合は実行時例外が返される.<br>
81          * ただし、システムプロパティ「appbase.dir」が明示的に設定されていれば、それが優先される.<br>
82          */
83         public synchronized static File getApplicationBaseDir() {
84                 if (applicationBaseDir == null) {
85                         
86                         String appbaseDir = System.getProperty("appbase.dir");
87                         if (appbaseDir != null && appbaseDir.length() > 0) {
88                                 // 明示的にアプリケーションベースディレクトリが指定されている場合.
89                                 try {
90                                         applicationBaseDir = new File(appbaseDir).getCanonicalFile();
91                                 } catch (IOException ex) {
92                                         ex.printStackTrace();
93                                         // 継続する.まだログの準備ができていない可能性が高いので標準エラー出力へ.
94                                 }
95                         }
96                         if (applicationBaseDir == null) {
97                                 // 明示的に指定されていない場合はコードの実行位置から割り出す.
98                                 ProtectionDomain pdomain = ConfigurationDirUtilities.class.getProtectionDomain();
99
100                                 CodeSource codeSource = pdomain.getCodeSource();
101                                 if (codeSource == null) {
102                                         throw new RuntimeException("codeSource is null: domain=" + pdomain);
103                                 }
104                                 
105                                 URL codeBaseUrl = codeSource.getLocation();
106                                 if (!codeBaseUrl.getProtocol().equals("file")) {
107                                         throw new RuntimeException("codeLocation is not file protocol.: " + codeBaseUrl);
108                                 }
109                                 
110                                 // クラスパスフォルダ、またはJARファイルの、その親
111                                 applicationBaseDir = new File(codeBaseUrl.getPath()).getParentFile();
112                                 
113                         }
114                 }
115                 return applicationBaseDir;
116         }
117         
118         /**
119          * デフォルトのユーザー固有のキャラクターデータディレクトリを取得する.<br>
120          * ユーザー固有のキャラクターディレクトリがまだ存在しない場合は作成される.<br>
121          * @return ユーザー固有のキャラクターデータディレクトリ
122          */
123         public static File getDefaultCharactersDir() {
124                 Logger logger = Logger.getLogger(ConfigurationDirUtilities.class.getName());
125                 File characterBaseDir = new File(ConfigurationDirUtilities.getUserDataDir(), "characters");
126                 if (!characterBaseDir.exists()) {
127                         if (!characterBaseDir.mkdirs()) {
128                                 logger.log(Level.WARNING, "can't create the charatcer base directory. " + characterBaseDir);
129                         }
130                 }
131                 return characterBaseDir;
132         }
133         
134 }