OSDN Git Service

move tyrLock()
[jindolf/Jindolf.git] / src / main / java / jp / sfjp / jindolf / config / ConfigStore.java
1 /*
2  * config store
3  *
4  * License : The MIT License
5  * Copyright(c) 2012 olyutorskii
6  */
7
8 package jp.sfjp.jindolf.config;
9
10 import java.nio.file.Files;
11 import java.nio.file.Path;
12 import java.nio.file.Paths;
13
14 /**
15  * Jindolf設定ディレクトリの管理を行う。
16  *
17  * <p>デフォルトの設定ディレクトリや
18  * アプリのコマンドライン引数から構成された、
19  * 設定ディレクトリに関する情報が保持管理される。
20  *
21  * <p>基本的に1アプリのみが設定ディレクトリへの入出力を許される。
22  *
23  * <p>インスタンス生成後に
24  * 設定ディレクトリを使わない設定に変更することが可能。
25  * (※ロック確保失敗後の続行等を想定)
26  *
27  * <p>設定ディレクトリには
28  *
29  * <ul>
30  * <li>ロックファイル
31  * <li>JSON設定ファイル
32  * <li>Avatar代替イメージ格納ディレクトリ
33  * </ul>
34  *
35  * <p>などが配置される。
36  *
37  * <p>コンストラクタに与えられるディレクトリは
38  * 絶対パスでなければならない。
39  *
40  * <p>ロックファイル取得の失敗、
41  * およびその後のユーザインタラクションによっては、
42  * 設定ディレクトリを使わない設定に上書きされた後
43  * 起動処理が続行される場合がありうる。
44  */
45 public class ConfigStore {
46
47     private static final Path JINCONF      = Paths.get("Jindolf");
48     private static final Path JINCONF_DOT  = Paths.get(".jindolf");
49     private static final Path LOCKFILE     = Paths.get("lock");
50     private static final Path LOCALIMG_DIR = Paths.get("img");
51
52     private static final Path MAC_LIB     = Paths.get("Library");
53     private static final Path MAC_APPSUPP = Paths.get("Application Support");
54
55
56     private boolean useStoreFile;
57     private Path configDir;
58
59
60     /**
61      * コンストラクタ。
62      *
63      * <p>このインスタンスでは、
64      * 設定ディレクトリへの入出力を行わない。
65      */
66     public ConfigStore(){
67         this(false, null);
68         return;
69     }
70
71     /**
72      * コンストラクタ。
73      *
74      * <p>このインスタンスでは、
75      * 設定ディレクトリへの入出力を行うが、
76      * デフォルトではない明示されたディレクトリが用いられる。
77      *
78      * @param configDirPath 設定ディレクトリの絶対パス。
79      *     nullの場合はデフォルトの設定ディレクトリが用いられる。
80      * @throws IllegalArgumentException 絶対パスではない。
81      */
82     public ConfigStore(Path configDirPath) throws IllegalArgumentException{
83         this(true, configDirPath);
84         return;
85     }
86
87     /**
88      * コンストラクタ。
89      *
90      * @param useStoreFile 設定ディレクトリ内への
91      *     入出力機能を使うならtrue
92      * @param configDirPath 設定ディレクトリの絶対パス。
93      *     設定ディレクトリを使わない場合は無視される。
94      *     この時点でのディレクトリ存在の有無は関知しない。
95      *     既存ディレクトリの各種属性チェックは後にチェックするものとする。
96      *     nullの場合デフォルトの設定ディレクトリが用いられる。
97      * @throws IllegalArgumentException 絶対パスではない。
98      */
99     protected ConfigStore(boolean useStoreFile,
100                           Path configDirPath )
101             throws IllegalArgumentException{
102         super();
103
104         this.useStoreFile = useStoreFile;
105
106         if(this.useStoreFile){
107             if(configDirPath != null){
108                 if( ! configDirPath.isAbsolute()){
109                     throw new IllegalArgumentException();
110                 }
111                 this.configDir = configDirPath;
112             }else{
113                 this.configDir = getDefaultConfDirPath();
114             }
115         }else{
116             this.configDir = null;
117         }
118
119         assert     (     this.useStoreFile  && this.configDir != null)
120                 || ( ( ! this.useStoreFile) && this.configDir == null);
121
122         return;
123     }
124
125
126     /**
127      * 暗黙的な設定格納ディレクトリを絶対パスで返す。
128      *
129      * <ul>
130      *
131      * <li>起動元JARファイルと同じディレクトリに、
132      * アクセス可能なディレクトリ"Jindolf"が
133      * すでに存在していればそれを返す。
134      *
135      * <li>起動元JARファイルおよび"Jindolf"が発見できなければ、
136      * MacOSX環境の場合"~/Library/Application Support/Jindolf/"を返す。
137      * Windows環境の場合"%USERPROFILE%\Jindolf\"を返す。
138      *
139      * <li>それ以外の環境(Linux,etc?)の場合"~/.jindolf/"を返す。
140      *
141      * </ul>
142      *
143      * <p>返すディレクトリが存在しているか否か、
144      * アクセス可能か否かは呼び出し元で判断せよ。
145      *
146      * @return 設定格納ディレクトリの絶対パス
147      */
148     public static Path getDefaultConfDirPath(){
149         Path jarParent = FileUtils.getJarDirectory();
150         if(FileUtils.isAccessibleDirectory(jarParent)){
151             Path confPath = jarParent.resolve(JINCONF);
152             if(FileUtils.isAccessibleDirectory(confPath)){
153                 assert confPath.isAbsolute();
154                 return confPath;
155             }
156         }
157
158         Path appset = getAppSetDir();
159
160         Path leaf;
161         if(FileUtils.isMacOSXFs() || FileUtils.isWindowsOSFs()){
162             leaf = JINCONF;
163         }else{
164             leaf = JINCONF_DOT;
165         }
166
167         Path result = appset.resolve(leaf);
168         assert result.isAbsolute();
169
170         return result;
171     }
172
173     /**
174      * アプリケーション設定ディレクトリを絶対パスで返す。
175      *
176      * <p>存在の有無、アクセスの可否は関知しない。
177      *
178      * <p>WindowsやLinuxではホームディレクトリ。
179      * Mac OS X ではさらにホームディレクトリの下の
180      * "Library/Application Support/"
181      *
182      * @return アプリケーション設定ディレクトリの絶対パス
183      */
184     private static Path getAppSetDir(){
185         Path home = getHomeDirectory();
186
187         Path result = home;
188
189         if(FileUtils.isMacOSXFs()){
190             result = result.resolve(MAC_LIB);
191             result = result.resolve(MAC_APPSUPP);
192         }
193
194         return result;
195     }
196
197     /**
198      * ホームディレクトリを得る。
199      *
200      * <p>システムプロパティuser.homeで示されたホームディレクトリを
201      * 絶対パスで返す。
202      *
203      * @return ホームディレクトリの絶対パス。
204      */
205     private static Path getHomeDirectory(){
206         String homeProp = System.getProperty("user.home");
207         Path result = Paths.get(homeProp);
208         result = result.toAbsolutePath();
209         return result;
210     }
211
212
213     /**
214      * 設定ディレクトリを使うか否か判定する。
215      *
216      * @return 設定ディレクトリを使うならtrue。
217      */
218     public boolean useStoreFile(){
219         return this.useStoreFile;
220     }
221
222     /**
223      * 設定ディレクトリを絶対パスで返す。
224      *
225      * @return 設定ディレクトリの絶対パス。
226      * 設定ディレクトリを使わない場合はnull
227      */
228     public Path getConfigDir(){
229         return this.configDir;
230     }
231
232     /**
233      * 設定ディレクトリを使わない設定に変更する。
234      */
235     public void setNoConf(){
236         this.useStoreFile = false;
237         this.configDir = null;
238         return;
239     }
240
241     /**
242      * ローカル画像格納ディレクトリを絶対パスで返す。
243      *
244      * @return 格納ディレクトリの絶対パス。
245      * 格納ディレクトリを使わない場合はnull
246      */
247     public Path getLocalImgDir(){
248         if( ! this.useStoreFile ) return null;
249         if(this.configDir == null) return null;
250
251         Path result = this.configDir.resolve(LOCALIMG_DIR);
252
253         return result;
254     }
255
256     /**
257      * ロックファイルを絶対パスで返す。
258      *
259      * @return ロックファイルの絶対パス。
260      * 格納ディレクトリを使わない場合はnull
261      */
262     public Path getLockFile(){
263         if( ! this.useStoreFile ) return null;
264         if(this.configDir == null) return null;
265
266         Path lockFile = this.configDir.resolve(LOCKFILE);
267
268         return lockFile;
269     }
270
271     /**
272      * 設定ディレクトリの存在を確認し、なければ作る。
273      *
274      * <p>設定ディレクトリを使わない場合は何もしない。
275      */
276     public void prepareConfigDir(){
277         if( ! this.useStoreFile ) return;
278
279         if( ! Files.exists(this.configDir) ){
280             Path created =
281                 ConfigDirUtils.buildConfDirPath(this.configDir);
282             ConfigDirUtils.checkDirPerm(created);
283         }else{
284             ConfigDirUtils.checkDirPerm(this.configDir);
285         }
286
287         Path imgDir = this.configDir.resolve("img");
288         if( ! Files.exists(imgDir) ){
289             ConfigDirUtils.buildImageCacheDir(imgDir);
290         }
291
292         return;
293     }
294
295 }