Revision | 1693 (tree) |
---|---|
Time | 2019-01-29 14:11:15 |
Author | takahashi_m |
(empty log message)
@@ -0,0 +1,12 @@ | ||
1 | +通常はJavaのjre/lib/extに入れて利用する | |
2 | + | |
3 | +pluginのコンパイルに必要なファイル | |
4 | +・sendgrid-java-4.1.1.jar | |
5 | +・java-http-client-4.1.0.jar | |
6 | + | |
7 | +その他は実行時に必要なファイル | |
8 | + | |
9 | +下記のファイルも必要となるが、5.9.25と重複しているので入れていない | |
10 | +・jackson-annotations-2.5.3.jar | |
11 | +・jackson-core-2.5.3.jar | |
12 | +・jackson-databind-2.5.3.jar |
@@ -1,3 +1,8 @@ | ||
1 | +5.10.8.0 (2019/02/01) | |
2 | + [bluemix用モジュール] | |
3 | + bluemix用のストレージpluginを利用する際に必要となります。 | |
4 | + 利用する場合はjre/lib/extに入れてください | |
5 | + | |
1 | 6 | 5.10.0.0 (2018/06/08) |
2 | 7 | [帳票エラーメールの改修] |
3 | 8 | FGNOMLをGE54に追加しました。 |
@@ -1,4 +1,25 @@ | ||
1 | -5.10.7.1 (2019/01/18) | |
1 | +5.10.8.0 (2019/02/01) | |
2 | + [クラウドストレージ対応] | |
3 | + ファイルの取り扱いの方法を整理して、クラウドストレージとローカルストレージを同じように扱えるようにします。 | |
4 | + このバージョンではストレージを共通で扱うクラスの追加のみを一旦行います。 | |
5 | + 利用するタグ等への適用は今後のバージョンで行う予定です。 | |
6 | + fukurou.model内にインターフェイスやファクトリクラス、標準クラス(ローカル用)を新たに追加します。 | |
7 | + クラウドストレージ用のクラスはplugin.cloud内に配置し、AWS,Azure,IBMCloud,OracleCloudのクラスを用意しておきます。 | |
8 | + クラウド用プラグインの利用には別途外部Jarが追加で必要なため、GEのChangesも参照ください。 | |
9 | + fukurou.model.FileOperation ファイル操作用インタフェイス | |
10 | + fukurou.model.AbstractFileOperation 実装Abstクラス | |
11 | + fukurou.model.DefaultFileOperation 標準ファイル操作用 | |
12 | + fukurou.model.FileOperationFactory ファクトリクラス | |
13 | + fukurou.model.FileOperationFileFilter フィルターインタフェイス | |
14 | + fukurou.model.FileOperationInfo ファイルList用Info | |
15 | + fukurou.util.HybsFileFilter 各クラスへのインターフェイスの追加 | |
16 | + hayabusa.io.HybsFileOperationFactory Hayabusaからの利用のためのクラス | |
17 | + plugin.cloud.FileOperation_AWS | |
18 | + plugin.cloud.FileOperation_AZURE | |
19 | + plugin.cloud.FileOperation_IBM | |
20 | + plugin.cloud.FileOperation_ORACLE | |
21 | + | |
22 | +5.10.7.1 (2019/01/18) | |
2 | 23 | [ViewForm_HTMLCalendar修正] |
3 | 24 | カレンダーViewは1件の場合にチェックボックスを出さない仕様になっていましたが、 |
4 | 25 | 2件以上との場合とのUI共通化のためチェックボックスを出すようにしておきます。 |
@@ -376,6 +397,12 @@ | ||
376 | 397 | hayabusa.common.SystemData#MAIL_DAEMON_LIMIT |
377 | 398 | hayabusa.mail.MailManager_DB#selGE30 |
378 | 399 | |
400 | +5.9.31.2 (2018/04/20) | |
401 | + [GE50シーケンス対応] | |
402 | + 5.9.31.1で対応したシーケンス対応をGE50でもしておきます。 | |
403 | + hayabusa.report.GE50Access#makeYkno() | |
404 | + | |
405 | + | |
379 | 406 | 5.9.31.1 (2018/04/13) |
380 | 407 | [エンジン内部のシーケンス取得] |
381 | 408 | エンジン内部でシーケンスの値を取得する際にfukurouを利用していない箇所があるため一部修正します。 |
@@ -0,0 +1,565 @@ | ||
1 | +package org.opengion.fukurou.model; | |
2 | + | |
3 | +import java.io.ByteArrayInputStream; | |
4 | +import java.io.ByteArrayOutputStream; | |
5 | +import java.io.File; | |
6 | +import java.io.FileNotFoundException; | |
7 | +import java.io.IOException; | |
8 | +import java.io.InputStream; | |
9 | +import java.util.ArrayList; | |
10 | +import java.util.List; | |
11 | + | |
12 | +import org.opengion.fukurou.util.Closer; | |
13 | +import org.opengion.fukurou.util.HybsFileFilter; | |
14 | +import org.opengion.fukurou.util.StringUtil; | |
15 | + | |
16 | +/** | |
17 | + * ファイル操作の抽象クラス | |
18 | + * | |
19 | + * 共通の処理等を実装しています。 | |
20 | + * | |
21 | + * @og.group ファイル操作 | |
22 | + * | |
23 | + * @og.rev 5.10.8.0 (2019/02/01) 新規作成 | |
24 | + * @og.auth oota | |
25 | + * @since JDK7.0 | |
26 | + */ | |
27 | +public abstract class AbstractFileOperation implements FileOperation { | |
28 | + | |
29 | + /* クラス定数 */ | |
30 | + private static final int BUFFER_SIZE = 1024 * 4; | |
31 | + /* クラス変数 */ | |
32 | + // パス | |
33 | + protected final String path; | |
34 | + // バケット名 | |
35 | + protected final String bucket; | |
36 | + | |
37 | + /** | |
38 | + * コンストラクタ | |
39 | + * ローカルサーバ用 | |
40 | + */ | |
41 | + public AbstractFileOperation() { | |
42 | + path = ""; | |
43 | + bucket = ""; | |
44 | + } | |
45 | + | |
46 | + /** | |
47 | + * コンストラクタ | |
48 | + * クラウドストレージ用 | |
49 | + * | |
50 | + * @param buket バケット | |
51 | + * @param inPath パス | |
52 | + */ | |
53 | + public AbstractFileOperation(final String buket , final String inPath) { | |
54 | + path = editPath(replaceFileSeparetor(inPath)); | |
55 | + this.bucket = buket; | |
56 | + | |
57 | + if (StringUtil.isNull(bucket)) { | |
58 | + String errMsg = "バケット未指定です。hayabusa利用ではシステム変数の「CLOUD_BUCKET」にバケット名を設定して下さい。"; | |
59 | + throw new RuntimeException(errMsg); | |
60 | + } | |
61 | + } | |
62 | + | |
63 | + /** | |
64 | + * InputStreamのデータを書き込みます。 | |
65 | + * | |
66 | + * @param is 書き込みデータのInputStream | |
67 | + * @throws IOException | |
68 | + */ | |
69 | + @Override | |
70 | + public void write(InputStream is) throws IOException { | |
71 | + String errMsg = "このクラスでは実装されていません。write(InputStream is)"; | |
72 | + throw new UnsupportedOperationException(errMsg); | |
73 | + } | |
74 | + | |
75 | + /** | |
76 | + * データを読み込み、InputStreamとして、返します。 | |
77 | + * | |
78 | + * @return 読み込みデータのInputStream | |
79 | + * @throws FileNotFoundException | |
80 | + */ | |
81 | + @Override | |
82 | + public InputStream read() throws FileNotFoundException { | |
83 | + String errMsg = "このクラスでは実装されていません。read()"; | |
84 | + throw new UnsupportedOperationException(errMsg); | |
85 | + } | |
86 | + | |
87 | + /** | |
88 | + * ファイルを削除します。 | |
89 | + * | |
90 | + * @return 成否フラグ | |
91 | + */ | |
92 | + @Override | |
93 | + public boolean delete() { | |
94 | + String errMsg = "このクラスでは実装されていません。delete()"; | |
95 | + throw new UnsupportedOperationException(errMsg); | |
96 | + } | |
97 | + | |
98 | + /** | |
99 | + * ファイルを指定先に、コピーします。 | |
100 | + * | |
101 | + * @param afPath コピー先 | |
102 | + * @return 成否フラグ | |
103 | + */ | |
104 | + @Override | |
105 | + public boolean copy(String afPath) { | |
106 | + String errMsg = "このクラスでは実装されていません。copy(String)"; | |
107 | + throw new UnsupportedOperationException(errMsg); | |
108 | + } | |
109 | + | |
110 | + /** | |
111 | + * ファイルを指定先に、移動します。 | |
112 | + * | |
113 | + * @param afPath 移動先 | |
114 | + * @return 成否フラグ | |
115 | + */ | |
116 | + @Override | |
117 | + public boolean move(String afPath) { | |
118 | + boolean flgRtn = false; | |
119 | + | |
120 | + flgRtn = copy(afPath); | |
121 | + if (flgRtn) { | |
122 | + flgRtn = delete(); | |
123 | + } | |
124 | + | |
125 | + return flgRtn; | |
126 | + } | |
127 | + | |
128 | + /** | |
129 | + * 設定パスを取得します。 | |
130 | + * | |
131 | + * @return 設定パス | |
132 | + */ | |
133 | + @Override | |
134 | + public String getPath() { | |
135 | + return path; | |
136 | + } | |
137 | + | |
138 | + /** | |
139 | + * 絶対パスを取得します。 | |
140 | + * | |
141 | + * @return 絶対パス | |
142 | + */ | |
143 | + @Override | |
144 | + public String getAbsolutePath() { | |
145 | + return path; | |
146 | + } | |
147 | + | |
148 | + /** | |
149 | + * 名称を取得します。 | |
150 | + * | |
151 | + * @return 名称 | |
152 | + */ | |
153 | + @Override | |
154 | + public String getName() { | |
155 | + return drawName(path); | |
156 | + } | |
157 | + | |
158 | + /** | |
159 | + * 親のパスを取得します。 | |
160 | + * | |
161 | + * @return 親のパス | |
162 | + */ | |
163 | + @Override | |
164 | + public String getParent() { | |
165 | + return drawParent(path); | |
166 | + } | |
167 | + | |
168 | + /** | |
169 | + * ファイルサイズを返します | |
170 | + * | |
171 | + * @return ファイルサイズ | |
172 | + */ | |
173 | + @Override | |
174 | + public long length() { | |
175 | + // TODO 自動生成されたメソッド・スタブ | |
176 | + return 0; | |
177 | + } | |
178 | + | |
179 | + /** | |
180 | + * 最終更新時刻を取得します。 | |
181 | + * | |
182 | + * @return 最終更新時刻 | |
183 | + */ | |
184 | + @Override | |
185 | + public long lastModified() { | |
186 | + // TODO 自動生成されたメソッド・スタブ | |
187 | + return 0; | |
188 | + } | |
189 | + | |
190 | + /** | |
191 | + * ファイルの場合は、trueを返します。 | |
192 | + * | |
193 | + * @return ファイルフラグ | |
194 | + */ | |
195 | + @Override | |
196 | + public boolean isFile() { | |
197 | + // TODO 自動生成されたメソッド・スタブ | |
198 | + return false; | |
199 | + } | |
200 | + | |
201 | + /** | |
202 | + * ディレクトリの場合は、trueを返します。 | |
203 | + * | |
204 | + * @return ディレクトリフラグ | |
205 | + */ | |
206 | + @Override | |
207 | + public boolean isDirectory() { | |
208 | + // TODO 自動生成されたメソッド・スタブ | |
209 | + return false; | |
210 | + } | |
211 | + | |
212 | + /** | |
213 | + * 存在する場合は、trueを返します。 | |
214 | + * | |
215 | + * @return 存在フラグ | |
216 | + */ | |
217 | + @Override | |
218 | + public boolean exists() { | |
219 | + return isDirectory() | isFile(); | |
220 | + } | |
221 | + | |
222 | + /** | |
223 | + * パスのファイルとディレクトリ一覧を取得します。 | |
224 | + * | |
225 | + * @return ファイルとティレクトリ一覧 | |
226 | + */ | |
227 | + @Override | |
228 | + public FileOperation[] listFiles() { | |
229 | + return listFiles(new HybsFileFilter()); | |
230 | + } | |
231 | + | |
232 | + /** | |
233 | + * パスのファイルとディレクトリ一覧を取得して、 | |
234 | + * 引数でフィルターを行います。 | |
235 | + * | |
236 | + * @param filter フィルター | |
237 | + * @return ファイルとディレクトリ一覧 | |
238 | + */ | |
239 | + @Override | |
240 | + public FileOperation[] listFiles(FileOperationFileFilter filter) { | |
241 | + String errMsg = "このクラスでは実装されていません。listFiles(FileOperationFileFilter)"; | |
242 | + throw new UnsupportedOperationException(errMsg); | |
243 | + } | |
244 | + | |
245 | + /** | |
246 | + * ディレクトリを作成します。 | |
247 | + * | |
248 | + * ※1つのディレクトリのみ作成します。 | |
249 | + * (クラウドストレージにはディレクトリの概念が無いため、 | |
250 | + * 作成は行わず、trueを返します) | |
251 | + * | |
252 | + * @return 成否フラグ | |
253 | + */ | |
254 | + @Override | |
255 | + public boolean mkdir() { | |
256 | + return true; | |
257 | + } | |
258 | + | |
259 | + /** | |
260 | + * ディレクトリを作成します。 | |
261 | + * | |
262 | + * ※複数のディレクトリを作成します。 | |
263 | + * (クラウドストレージにはディレクトリの概念が無いため、 | |
264 | + * 作成は行わず、trueを返します) | |
265 | + * | |
266 | + * @return 成否フラグ | |
267 | + */ | |
268 | + @Override | |
269 | + public boolean mkdirs() { | |
270 | + return true; | |
271 | + } | |
272 | + | |
273 | + /** | |
274 | + * 指定のファイル情報のファイル名に変更します。 | |
275 | + * | |
276 | + * @param dest 変更後のファイル情報 | |
277 | + * @return 成否フラグ | |
278 | + */ | |
279 | + @Override | |
280 | + public boolean renameTo(FileOperation dest) { | |
281 | + return move(dest.getPath()); | |
282 | + } | |
283 | + | |
284 | + /** | |
285 | + * 親のディレクトリを返します。 | |
286 | + * | |
287 | + * @return 親のディレクトリ | |
288 | + */ | |
289 | + @Override | |
290 | + public FileOperation getParentFile() { | |
291 | + return null; | |
292 | + } | |
293 | + | |
294 | + /** | |
295 | + * 書き込み可能フラグ | |
296 | + * | |
297 | + * ※クラウドストレージの場合は、 | |
298 | + * 必ずtrueを返します。 | |
299 | + * | |
300 | + * @return 書き込み可能フラグ | |
301 | + */ | |
302 | + @Override | |
303 | + public boolean canWrite() { | |
304 | + return true; | |
305 | + } | |
306 | + | |
307 | + /** | |
308 | + * 読み取り可能フラグ | |
309 | + * | |
310 | + * ※クラウドストレージの場合は、 | |
311 | + * 必ずtrueを返します。 | |
312 | + * | |
313 | + * @return 読み取り可能フラグ | |
314 | + */ | |
315 | + @Override | |
316 | + public boolean canRead() { | |
317 | + return true; | |
318 | + } | |
319 | + | |
320 | + /** | |
321 | + * 隠しファイルフラグ | |
322 | + * | |
323 | + * ※クラウドストレージの場合は、 | |
324 | + * 必ずfalseを返します。 | |
325 | + * | |
326 | + * @return 隠しファイルフラグ | |
327 | + */ | |
328 | + @Override | |
329 | + public boolean isHidden() { | |
330 | + return false; | |
331 | + } | |
332 | + | |
333 | + /** | |
334 | + * 新規ファイル作成 | |
335 | + * | |
336 | + * 既にファイルが存在しない場合のみ、 | |
337 | + * 空のファイルを作成します。 | |
338 | + * | |
339 | + * @return 成否フラグ | |
340 | + * @throws IOException | |
341 | + */ | |
342 | + @Override | |
343 | + public boolean createNewFile() throws IOException { | |
344 | + boolean rtn = false; | |
345 | + | |
346 | + if (!exists()) { | |
347 | + InputStream is = null; | |
348 | + try { | |
349 | + is = new ByteArrayInputStream(new byte[0]); | |
350 | + write(is); | |
351 | + rtn = true; | |
352 | + } finally { | |
353 | + Closer.ioClose(is); | |
354 | + } | |
355 | + } | |
356 | + | |
357 | + return rtn; | |
358 | + } | |
359 | + | |
360 | + /** | |
361 | + * 最終更新時刻の更新 | |
362 | + * | |
363 | + * 最終更新時刻の更新を行います。 | |
364 | + * ※クラウドストレージの場合は、 | |
365 | + * 最終更新時刻の更新を行えません。 | |
366 | + * | |
367 | + * @param time 更新する最終更新時刻 | |
368 | + * @return 成否フラグ | |
369 | + */ | |
370 | + @Override | |
371 | + public boolean setLastModified(long time) { | |
372 | + // クラウドストレージでは、setLastModifiedによる、 | |
373 | + // 最終更新時刻の設定はできないので、 | |
374 | + // 処理を行わずにtrueを返します。 | |
375 | + return true; | |
376 | + } | |
377 | + | |
378 | + /** | |
379 | + * カノニカルファイル情報の取得 | |
380 | + * | |
381 | + * ※ローカルサーバのみ通常ファイルと、 | |
382 | + * カノニカルファイルで異なります。 | |
383 | + * | |
384 | + * @return カノニカルファイル情報 | |
385 | + * @throws IOException | |
386 | + */ | |
387 | + @Override | |
388 | + public FileOperation getCanonicalFile() throws IOException { | |
389 | + return this; | |
390 | + } | |
391 | + | |
392 | + /** | |
393 | + * toStringメソッド | |
394 | + * パスを返します。 | |
395 | + */ | |
396 | + @Override | |
397 | + public String toString() { | |
398 | + return path; | |
399 | + } | |
400 | + | |
401 | + /** 共通関数 **/ | |
402 | + /** | |
403 | + * ファイルパスの編集 2018/05/07 ADD | |
404 | + * パスの先頭が「/」の場合は「/」の除去と、「//」を「/」に置換処理の追加。 | |
405 | + * | |
406 | + * @og.rev 5.9.32.1 (2018/05/11) | |
407 | + * @param path | |
408 | + * @return 変更後パス | |
409 | + */ | |
410 | + protected String editPath(final String path) { | |
411 | + if (StringUtil.isNull(path)) { | |
412 | + return ""; | |
413 | + } | |
414 | + | |
415 | + String rtn = path; | |
416 | + // 先頭が「/」の場合は除去 | |
417 | + if ("/".equals(rtn.substring(0, 1))) { | |
418 | + rtn = rtn.substring(1); | |
419 | + } | |
420 | + // 「//」は「/」に置換 | |
421 | + rtn = rtn.replaceAll("//", "/"); | |
422 | + // 後尾の「.」は除去 | |
423 | + rtn = rTrim(rtn, '.'); | |
424 | + // 後尾の「/」は除去 | |
425 | + rtn = rTrim(rtn, '/'); | |
426 | + | |
427 | + return rtn; | |
428 | + } | |
429 | + | |
430 | + /** | |
431 | + * キーから親のパスを抽出します。 | |
432 | + * | |
433 | + * @param key キー | |
434 | + * @return 親のパス | |
435 | + */ | |
436 | + protected String drawParent(String key) { | |
437 | + int k = key.lastIndexOf("/"); | |
438 | + | |
439 | + String rtn = ""; | |
440 | + if (k > 0) { | |
441 | + rtn = key.substring(0, key.lastIndexOf("/")); | |
442 | + } | |
443 | + if ("/".equals(File.separator)) { | |
444 | + rtn = File.separator + rtn; | |
445 | + } | |
446 | + | |
447 | + return rtn; | |
448 | + } | |
449 | + | |
450 | + /** | |
451 | + * 引数のkeyから名称を抽出します。 | |
452 | + * | |
453 | + * @param key キー(パス) | |
454 | + * @return 名称 | |
455 | + */ | |
456 | + protected String drawName(String key) { | |
457 | + int k = key.lastIndexOf("/"); | |
458 | + | |
459 | + String rtn = key; | |
460 | + if (k > 0) { | |
461 | + rtn = key.substring(key.lastIndexOf("/") + 1); | |
462 | + } | |
463 | + return rtn; | |
464 | + } | |
465 | + | |
466 | + /** | |
467 | + * 後尾に「/」がない場合は、付与します。 | |
468 | + * | |
469 | + * @param path パス | |
470 | + * @return 後尾に「/」ありのパス | |
471 | + */ | |
472 | + protected String setDirTail(String path) { | |
473 | + if (StringUtil.isNull(path)) { | |
474 | + return path; | |
475 | + } | |
476 | + | |
477 | + StringBuilder sb = new StringBuilder(path); | |
478 | + if (!"/".equals(path.substring(path.length() - 1))) { | |
479 | + sb.append("/"); | |
480 | + } | |
481 | + return sb.toString(); | |
482 | + } | |
483 | + | |
484 | + /** | |
485 | + * 右側の文字が、指定の文字の場合、除去します。 | |
486 | + * | |
487 | + * @param str 対象文字列 | |
488 | + * @param chr 指定文字 | |
489 | + * @return 右側から指定文字を除去後の文字列 | |
490 | + */ | |
491 | + protected String rTrim(final String str, char chr) { | |
492 | + String rtn = str; | |
493 | + int trgPos = 0; | |
494 | + for (int i = str.length() - 1; i >= 0; i--) { | |
495 | + if (str.charAt(i) == chr) { | |
496 | + trgPos = i; | |
497 | + // すべて合致した場合は、から文字を返す | |
498 | + if (trgPos == 0) { | |
499 | + rtn = ""; | |
500 | + } | |
501 | + } else { | |
502 | + break; | |
503 | + } | |
504 | + } | |
505 | + | |
506 | + if (trgPos > 0) { | |
507 | + rtn = str.substring(0, trgPos); | |
508 | + } | |
509 | + | |
510 | + return rtn; | |
511 | + } | |
512 | + | |
513 | + /** | |
514 | + * ファイル区切り文字を変換します。 | |
515 | + * | |
516 | + * @param path 変換前文字列 | |
517 | + * @return 返還後文字列 | |
518 | + */ | |
519 | + protected String replaceFileSeparetor(final String path) { | |
520 | + if (StringUtil.isNull(path)) { | |
521 | + return ""; | |
522 | + } | |
523 | + | |
524 | + return path.replaceAll("\\\\", "/"); | |
525 | + } | |
526 | + | |
527 | + /** | |
528 | + * フィルター処理を行う | |
529 | + * | |
530 | + * @param list フィルタを行うリスト | |
531 | + * @param filter フィルタ情報 | |
532 | + * @return フィルタ後のリスト | |
533 | + */ | |
534 | + protected FileOperation[] filter(List<FileOperationInfo> list, FileOperationFileFilter filter) { | |
535 | + ArrayList<FileOperationInfo> files = new ArrayList<FileOperationInfo>(); | |
536 | + for (int i = 0; i < list.size(); i++) { | |
537 | + if (filter.accept(list.get(i))) { | |
538 | + files.add(list.get(i)); | |
539 | + } | |
540 | + } | |
541 | + return files.toArray(new FileOperationInfo[files.size()]); | |
542 | + } | |
543 | + | |
544 | + /** | |
545 | + * InputStreamをbyte[]に変換。 | |
546 | + * InputStreamのサイズ計算に利用。 | |
547 | + * | |
548 | + * @param is byte[]変換するInputStream | |
549 | + * @return InpusStreamをbyte[]に変換した値 | |
550 | + */ | |
551 | + protected byte[] toByteArray(InputStream is) throws IOException { | |
552 | + ByteArrayOutputStream output = new ByteArrayOutputStream(); | |
553 | + try { | |
554 | + byte[] b = new byte[BUFFER_SIZE]; | |
555 | + int n = 0; | |
556 | + while ((n = is.read(b)) != -1) { | |
557 | + output.write(b, 0, n); | |
558 | + } | |
559 | + return output.toByteArray(); | |
560 | + } finally { | |
561 | + output.close(); | |
562 | + } | |
563 | + } | |
564 | +} | |
565 | + |
@@ -0,0 +1,469 @@ | ||
1 | +package org.opengion.fukurou.model; | |
2 | + | |
3 | +import java.io.File; | |
4 | +import java.io.FileInputStream; | |
5 | +import java.io.FileNotFoundException; | |
6 | +import java.io.IOException; | |
7 | +import java.io.InputStream; | |
8 | +import java.nio.file.Files; | |
9 | +import java.nio.file.Paths; | |
10 | +import java.nio.file.StandardCopyOption; | |
11 | +import java.util.ArrayList; | |
12 | +import java.util.List; | |
13 | + | |
14 | +import org.opengion.fukurou.util.HybsFileFilter; | |
15 | + | |
16 | +/** | |
17 | + * ローカルサーバのファイル操作クラス | |
18 | + * | |
19 | + * FileOperationFactoryでデフォルトとして設定されており、 | |
20 | + * ローカルサーバでのファイル操作を行います。 | |
21 | + * ※java.io.Fileと同等のファイル操作になります。 | |
22 | + * | |
23 | + * @og.group ファイル操作 | |
24 | + * | |
25 | + * @og.rev 5.10.8.0 (2019/02/01) 新規作成 | |
26 | + * @author oota | |
27 | + * @sinse JDK7.0 | |
28 | + */ | |
29 | +public class DefaultFileOperation extends AbstractFileOperation { | |
30 | + // ファイル操作用 | |
31 | + private final File file; | |
32 | + | |
33 | + /** | |
34 | + * コンストラクタ | |
35 | + * | |
36 | + * 引数のパスから、java.io.Fileインスタンスを生成します。 | |
37 | + * @param inPath ファイルパス | |
38 | + * | |
39 | + */ | |
40 | + public DefaultFileOperation(String inPath) { | |
41 | + file = new File(inPath); | |
42 | + } | |
43 | + | |
44 | + /** | |
45 | + * InputStreamのデータを書き込みます。 | |
46 | + * | |
47 | + * @param is 書き込みデータのInputStream | |
48 | + * @throws IOException | |
49 | + */ | |
50 | + @Override | |
51 | + public void write(final InputStream is) throws IOException { | |
52 | + // InpustStreamを対象パスに出力 | |
53 | + Files.copy(is, Paths.get(file.getPath()), StandardCopyOption.REPLACE_EXISTING); | |
54 | + } | |
55 | + | |
56 | + /** | |
57 | + * データを読み込み、InputStreamとして、返します。 | |
58 | + * | |
59 | + * @return 読み込みデータのInputStream | |
60 | + * @throws FileNotFoundException | |
61 | + */ | |
62 | + @Override | |
63 | + public InputStream read() throws FileNotFoundException { | |
64 | + return new FileInputStream(file.getPath()); | |
65 | + } | |
66 | + | |
67 | + /** | |
68 | + * ファイルを削除します。 | |
69 | + * | |
70 | + * @return 成否フラグ | |
71 | + */ | |
72 | + @Override | |
73 | + public boolean delete() { | |
74 | + return file.delete(); | |
75 | + } | |
76 | + | |
77 | + /** | |
78 | + * ファイルを指定先に、コピーします。 | |
79 | + * | |
80 | + * @param afPath コピー先 | |
81 | + * @return 成否フラグ | |
82 | + */ | |
83 | + @Override | |
84 | + public boolean copy(String afPath) { | |
85 | + boolean flgRtn = false; | |
86 | + | |
87 | + try { | |
88 | + // 指定パスのファイルを、指定先にコピー from;jdk7 | |
89 | + Files.copy(Paths.get(file.getPath()), Paths.get(afPath), StandardCopyOption.REPLACE_EXISTING); | |
90 | + flgRtn = true; | |
91 | + } catch (IOException ie) { | |
92 | + // スルーしてfalseを返す | |
93 | + } | |
94 | + | |
95 | + return flgRtn; | |
96 | + } | |
97 | + | |
98 | + /** | |
99 | + * ファイルを指定先に、移動します。 | |
100 | + * | |
101 | + * @param afPath 移動先 | |
102 | + * @return 成否フラグ | |
103 | + */ | |
104 | + @Override | |
105 | + public boolean move(String afPath) { | |
106 | + boolean flgRtn = false; | |
107 | + | |
108 | + try { | |
109 | + // 指定パスのファイルを、指定先に移動 from:jdk7 | |
110 | + Files.move(Paths.get(file.getPath()), Paths.get(afPath), StandardCopyOption.REPLACE_EXISTING); | |
111 | + flgRtn = true; | |
112 | + } catch (IOException ie) { | |
113 | + // スルーしてfalseを返す | |
114 | + } | |
115 | + return flgRtn; | |
116 | + } | |
117 | + | |
118 | + /** | |
119 | + * 設定パスを取得します。 | |
120 | + * | |
121 | + * @return 設定パス | |
122 | + */ | |
123 | + @Override | |
124 | + public String getPath() { | |
125 | + return file.getPath(); | |
126 | + } | |
127 | + | |
128 | + /** | |
129 | + * 絶対パスを取得します。 | |
130 | + * | |
131 | + * @return 絶対パス | |
132 | + */ | |
133 | + @Override | |
134 | + public String getAbsolutePath() { | |
135 | + return file.getAbsolutePath(); | |
136 | + } | |
137 | + | |
138 | + /** | |
139 | + * 名称を取得します。 | |
140 | + * | |
141 | + * @return 名称 | |
142 | + */ | |
143 | + @Override | |
144 | + public String getName() { | |
145 | + return file.getName(); | |
146 | + } | |
147 | + | |
148 | + /** | |
149 | + * 親のパスを取得します。 | |
150 | + * | |
151 | + * @return 親のパス | |
152 | + */ | |
153 | + @Override | |
154 | + public String getParent() { | |
155 | + return file.getParent(); | |
156 | + } | |
157 | + | |
158 | + /** | |
159 | + * ファイルサイズを返します | |
160 | + * | |
161 | + * @return ファイルサイズ | |
162 | + */ | |
163 | + @Override | |
164 | + public long length() { | |
165 | + return file.length(); | |
166 | + } | |
167 | + | |
168 | + /** | |
169 | + * 最終更新時刻を取得します。 | |
170 | + * | |
171 | + * @return 最終更新時刻 | |
172 | + */ | |
173 | + @Override | |
174 | + public long lastModified() { | |
175 | + return file.lastModified(); | |
176 | + } | |
177 | + | |
178 | + /** | |
179 | + * ファイルの場合は、trueを返します。 | |
180 | + * | |
181 | + * @return ファイルフラグ | |
182 | + */ | |
183 | + @Override | |
184 | + public boolean isFile() { | |
185 | + return file.isFile(); | |
186 | + } | |
187 | + | |
188 | + /** | |
189 | + * ディレクトリの場合は、trueを返します。 | |
190 | + * | |
191 | + * @return ディレクトリフラグ | |
192 | + */ | |
193 | + @Override | |
194 | + public boolean isDirectory() { | |
195 | + return file.isDirectory(); | |
196 | + } | |
197 | + | |
198 | + /** | |
199 | + * 存在する場合は、trueを返します。 | |
200 | + * | |
201 | + * @return 存在フラグ | |
202 | + */ | |
203 | + @Override | |
204 | + public boolean exists() { | |
205 | + return file.exists(); | |
206 | + } | |
207 | + | |
208 | + /** | |
209 | + * パスのファイルとディレクトリ一覧を取得します。 | |
210 | + * | |
211 | + * @return ファイルとティレクトリ一覧 | |
212 | + */ | |
213 | + @Override | |
214 | + public FileOperation[] listFiles() { | |
215 | + return listFiles(new HybsFileFilter()); | |
216 | + } | |
217 | + | |
218 | + /** | |
219 | + * パスのファイルとディレクトリ一覧を取得して、 | |
220 | + * 引数でフィルターを行います。 | |
221 | + * | |
222 | + * @param filter フィルター | |
223 | + * @return ファイルとディレクトリ一覧 | |
224 | + */ | |
225 | + @Override | |
226 | + public FileOperation[] listFiles(FileOperationFileFilter filter) { | |
227 | + // 存在チェック | |
228 | + if (!exists()) { | |
229 | + return new FileOperationInfo[0]; | |
230 | + } | |
231 | + | |
232 | + // カノニカルファイル取得 | |
233 | + File trg = null; | |
234 | + try { | |
235 | + trg = file.getCanonicalFile(); | |
236 | + } catch (IOException ie) { | |
237 | + return new FileOperationInfo[0]; | |
238 | + } | |
239 | + | |
240 | + // 直下のファイルとディレクトリ情報の取得 | |
241 | + File[] files = trg.listFiles(); | |
242 | + | |
243 | + // 取得情報をリストに格納 | |
244 | + List<FileOperationInfo> fileList = new ArrayList<FileOperationInfo>(); | |
245 | + for (File file : files) { | |
246 | + FileOperationInfo info = new FileOperationInfo(); | |
247 | + | |
248 | + info.setPath(file.getPath()); | |
249 | + info.setName(file.getName()); | |
250 | + info.setParent(file.getParent()); | |
251 | + info.setLastModifiedValue(file.lastModified()); | |
252 | + info.setCanWrite(file.canWrite()); | |
253 | + info.setCanRead(file.canRead()); | |
254 | + info.setHidden(file.isHidden()); | |
255 | + | |
256 | + if (file.isFile()) { | |
257 | + // ファイル情報 | |
258 | + info.setFile(true); | |
259 | + info.setSize(file.length()); | |
260 | + } else if (file.isDirectory()) { | |
261 | + // ディレクトリ情報 | |
262 | + info.setDirectory(true); | |
263 | + } | |
264 | + | |
265 | + fileList.add(info); | |
266 | + } | |
267 | + | |
268 | + // フィルタ処理 | |
269 | + FileOperation[] rtnArray = filter(fileList, filter); | |
270 | + | |
271 | + return rtnArray; | |
272 | + } | |
273 | + | |
274 | + /** | |
275 | + * ディレクトリを作成します。 | |
276 | + * | |
277 | + * ※1つのディレクトリのみ作成します。 | |
278 | + * (クラウドストレージにはディレクトリの概念が無いため、 | |
279 | + * 作成は行わず、trueを返します) | |
280 | + * | |
281 | + * @return 成否フラグ | |
282 | + */ | |
283 | + @Override | |
284 | + public boolean mkdir() { | |
285 | + return file.mkdir(); | |
286 | + } | |
287 | + | |
288 | + /** | |
289 | + * ディレクトリを作成します。 | |
290 | + * | |
291 | + * ※複数のディレクトリを作成します。 | |
292 | + * (クラウドストレージにはディレクトリの概念が無いため、 | |
293 | + * 作成は行わず、trueを返します) | |
294 | + * | |
295 | + * @return 成否フラグ | |
296 | + */ | |
297 | + @Override | |
298 | + public boolean mkdirs() { | |
299 | + return file.mkdirs(); | |
300 | + } | |
301 | + | |
302 | + /** | |
303 | + * 指定のファイル情報のファイル名に変更します。 | |
304 | + * | |
305 | + * @param dest 変更後のファイル情報 | |
306 | + * @return 成否フラグ | |
307 | + */ | |
308 | + @Override | |
309 | + public boolean renameTo(FileOperation dest) { | |
310 | + return file.renameTo(new File(dest.getPath())); | |
311 | + } | |
312 | + | |
313 | + /** | |
314 | + * 親のディレクトリを返します。 | |
315 | + * | |
316 | + * @return 親のディレクトリ | |
317 | + */ | |
318 | + @Override | |
319 | + public FileOperation getParentFile() { | |
320 | + return new DefaultFileOperation(getParent()); | |
321 | + } | |
322 | + | |
323 | + /** | |
324 | + * 書き込み可能フラグ | |
325 | + * | |
326 | + * ※クラウドストレージの場合は、 | |
327 | + * 必ずtrueを返します。 | |
328 | + * | |
329 | + * @return 書き込み可能フラグ | |
330 | + */ | |
331 | + @Override | |
332 | + public boolean canWrite() { | |
333 | + return file.canWrite(); | |
334 | + } | |
335 | + | |
336 | + /** | |
337 | + * 読み取り可能フラグ | |
338 | + * | |
339 | + * ※クラウドストレージの場合は、 | |
340 | + * 必ずtrueを返します。 | |
341 | + * | |
342 | + * @return 読み取り可能フラグ | |
343 | + */ | |
344 | + @Override | |
345 | + public boolean canRead() { | |
346 | + return file.canRead(); | |
347 | + } | |
348 | + | |
349 | + /** | |
350 | + * 隠しファイルフラグ | |
351 | + * | |
352 | + * ※クラウドストレージの場合は、 | |
353 | + * 必ずfalseを返します。 | |
354 | + * | |
355 | + * @return 隠しファイルフラグ | |
356 | + */ | |
357 | + @Override | |
358 | + public boolean isHidden() { | |
359 | + return file.isHidden(); | |
360 | + } | |
361 | + | |
362 | + /** | |
363 | + * 新規ファイル作成 | |
364 | + * | |
365 | + * 既にファイルが存在しない場合のみ、 | |
366 | + * 空のファイルを作成します。 | |
367 | + * | |
368 | + * @return 成否フラグ | |
369 | + * @throws IOException | |
370 | + */ | |
371 | + @Override | |
372 | + public boolean createNewFile() throws IOException { | |
373 | + return file.createNewFile(); | |
374 | + } | |
375 | + | |
376 | + /** | |
377 | + * 最終更新時刻の更新 | |
378 | + * | |
379 | + * 最終更新時刻の更新を行います。 | |
380 | + * ※クラウドストレージの場合は、 | |
381 | + * 最終更新時刻の更新を行えません。 | |
382 | + * | |
383 | + * @param time 更新する最終更新時刻 | |
384 | + * @return 成否フラグ | |
385 | + */ | |
386 | + @Override | |
387 | + public boolean setLastModified(long time) { | |
388 | + return file.setLastModified(time); | |
389 | + } | |
390 | + | |
391 | + /** | |
392 | + * カノニカルファイル情報を取得します。 | |
393 | + * | |
394 | + * ※ローカルサーバのみ通常ファイルと、 | |
395 | + * カノニカルファイルで異なります。 | |
396 | + * | |
397 | + * @return カノニカルファイル情報 | |
398 | + * @throws IOException | |
399 | + */ | |
400 | + @Override | |
401 | + public FileOperation getCanonicalFile() throws IOException { | |
402 | + File path = file.getCanonicalFile(); | |
403 | + return new DefaultFileOperation(path.getPath()); | |
404 | + } | |
405 | + | |
406 | + /** | |
407 | + * toStringでは、パスを返します。 | |
408 | + * | |
409 | + * @return パス | |
410 | + */ | |
411 | + @Override | |
412 | + public String toString() { | |
413 | + return getPath(); | |
414 | + } | |
415 | + | |
416 | + /** | |
417 | + * テスト用メソッドです | |
418 | + * | |
419 | + * @param args | |
420 | + */ | |
421 | + public static void main(String[] args) { | |
422 | + // listTest(); | |
423 | + // methodTest(); | |
424 | + } | |
425 | + /* テスト用 | |
426 | + // リストテスト用 | |
427 | + public static void listTest() { | |
428 | + String path = ""; | |
429 | + FileOperation file = new DefaultFileOperation(path); | |
430 | + | |
431 | + try { | |
432 | + // フィルタを行う場合 | |
433 | + // 以下の場合は、bで始まるファイルと、全てのディレクトリ(指定パスの直下)が取得されます。 | |
434 | + // HybsFileOperationFileFilter filter = new HybsFileOperationFileFilter(); | |
435 | + HybsFileFilter filter = new HybsFileFilter(true); | |
436 | + filter.startsWith("b"); | |
437 | + | |
438 | + FileOperation[] list = file.getCanonicalFile().listFiles(filter); | |
439 | + | |
440 | + System.out.println(list.length); | |
441 | + for(FileOperation f: list) { | |
442 | + System.out.println(f.getPath()); | |
443 | + } | |
444 | + }catch(Exception e) { | |
445 | + System.out.println(e.getMessage()); | |
446 | + } | |
447 | + } | |
448 | + | |
449 | + // メソッドテスト用 | |
450 | + public static void methodTest() { | |
451 | + String path = "H:/tmp/test/newfile.txt"; | |
452 | + FileOperation file = new DefaultFileOperation(path); | |
453 | + | |
454 | + String afPath = "H:/tmp/test/af.txt"; | |
455 | + FileOperation af = new DefaultFileOperation(afPath); | |
456 | + | |
457 | + try { | |
458 | + boolean rtn = | |
459 | + //file.renameTo(af); | |
460 | + file.createNewFile(); | |
461 | + //file.mkdirs(); | |
462 | + //file.getCanonicalFile().exists(); | |
463 | + System.out.println(rtn); | |
464 | + }catch(Exception e) { | |
465 | + System.out.println(e.getMessage()); | |
466 | + } | |
467 | + } | |
468 | + //*/ | |
469 | +} |
@@ -0,0 +1,238 @@ | ||
1 | +package org.opengion.fukurou.model; | |
2 | + | |
3 | +import java.io.FileNotFoundException; | |
4 | +import java.io.IOException; | |
5 | +import java.io.InputStream; | |
6 | + | |
7 | +/** | |
8 | + * ファイル操作のインタフェース | |
9 | + * | |
10 | + * ローカルサーバ、クラウドストレージ(AWS,AZURE,BLUEMIX,ORACLE)のファイル操作用です。 | |
11 | + * FileOperationFactoryを通して、インスタンスを生成可能です。 | |
12 | + * | |
13 | + * @og.group ファイル操作 | |
14 | + * | |
15 | + * @og.rev 5.10.8.0 (2019/02/01) 新規作成 | |
16 | + * @author oota | |
17 | + * @since JDK7.0 | |
18 | + */ | |
19 | +public interface FileOperation { | |
20 | + /** | |
21 | + * InputStreamのデータを書き込みます。 | |
22 | + * | |
23 | + * @param is 書き込みデータのInputStream | |
24 | + * @throws IOException | |
25 | + */ | |
26 | + public void write(InputStream is) throws IOException; | |
27 | + | |
28 | + /** | |
29 | + * データを読み込み、InputStreamとして、返します。 | |
30 | + * | |
31 | + * @return 読み込みデータのInputStream | |
32 | + * @throws FileNotFoundException | |
33 | + */ | |
34 | + public InputStream read() throws FileNotFoundException; | |
35 | + | |
36 | + /** | |
37 | + * ファイルを削除します。 | |
38 | + * | |
39 | + * @return 成否フラグ | |
40 | + */ | |
41 | + public boolean delete(); | |
42 | + | |
43 | + /** | |
44 | + * ファイルを指定先に、コピーします。 | |
45 | + * | |
46 | + * @param afPath コピー先 | |
47 | + * @return 成否フラグ | |
48 | + */ | |
49 | + public boolean copy(String afPath); | |
50 | + | |
51 | + /** | |
52 | + * ファイルを指定先に、移動します。 | |
53 | + * | |
54 | + * @param afPath 移動先 | |
55 | + * @return 成否フラグ | |
56 | + */ | |
57 | + public boolean move(String afPath); | |
58 | + | |
59 | + /** | |
60 | + * 設定パスを取得します。 | |
61 | + * | |
62 | + * @return 設定パス | |
63 | + */ | |
64 | + public String getPath(); | |
65 | + | |
66 | + /** | |
67 | + * 絶対パスを取得します。 | |
68 | + * | |
69 | + * @return 絶対パス | |
70 | + */ | |
71 | + public String getAbsolutePath(); | |
72 | + | |
73 | + /** | |
74 | + * 名称を取得します。 | |
75 | + * | |
76 | + * @return 名称 | |
77 | + */ | |
78 | + public String getName(); | |
79 | + | |
80 | + /** | |
81 | + * 親のパスを取得します。 | |
82 | + * | |
83 | + * @return 親のパス | |
84 | + */ | |
85 | + public String getParent(); | |
86 | + | |
87 | + /** | |
88 | + * ファイルサイズを返します | |
89 | + * | |
90 | + * @return ファイルサイズ | |
91 | + */ | |
92 | + public long length(); | |
93 | + | |
94 | + /** | |
95 | + * 最終更新時刻を取得します。 | |
96 | + * | |
97 | + * @return 最終更新時刻 | |
98 | + */ | |
99 | + public long lastModified(); | |
100 | + | |
101 | + /** | |
102 | + * ファイルの場合は、trueを返します。 | |
103 | + * | |
104 | + * @return ファイルフラグ | |
105 | + */ | |
106 | + public boolean isFile(); | |
107 | + | |
108 | + /** | |
109 | + * ディレクトリの場合は、trueを返します。 | |
110 | + * | |
111 | + * @return ディレクトリフラグ | |
112 | + */ | |
113 | + public boolean isDirectory(); | |
114 | + | |
115 | + /** | |
116 | + * 存在する場合は、trueを返します。 | |
117 | + * | |
118 | + * @return 存在フラグ | |
119 | + */ | |
120 | + public boolean exists(); | |
121 | + | |
122 | + /** | |
123 | + * パスのファイルとディレクトリ一覧を取得します。 | |
124 | + * | |
125 | + * @return ファイルとティレクトリ一覧 | |
126 | + */ | |
127 | + public FileOperation[] listFiles(); | |
128 | + | |
129 | + /** | |
130 | + * パスのファイルとディレクトリ一覧を取得して、 | |
131 | + * 引数でフィルターを行います。 | |
132 | + * | |
133 | + * @param filter フィルター | |
134 | + * @return ファイルとディレクトリ一覧 | |
135 | + */ | |
136 | + public FileOperation[] listFiles(FileOperationFileFilter filter); | |
137 | + | |
138 | + /** | |
139 | + * ディレクトリを作成します。 | |
140 | + * | |
141 | + * ※1つのディレクトリのみ作成します。 | |
142 | + * (クラウドストレージにはディレクトリの概念が無いため、 | |
143 | + * 作成は行わず、trueを返します) | |
144 | + * | |
145 | + * @return 成否フラグ | |
146 | + */ | |
147 | + public boolean mkdir(); | |
148 | + | |
149 | + /** | |
150 | + * ディレクトリを作成します。 | |
151 | + * | |
152 | + * ※複数のディレクトリを作成します。 | |
153 | + * (クラウドストレージにはディレクトリの概念が無いため、 | |
154 | + * 作成は行わず、trueを返します) | |
155 | + * | |
156 | + * @return 成否フラグ | |
157 | + */ | |
158 | + public boolean mkdirs(); | |
159 | + | |
160 | + /** | |
161 | + * 指定のファイル情報のファイル名に変更します。 | |
162 | + * | |
163 | + * @param dest 変更後のファイル情報 | |
164 | + * @return 成否フラグ | |
165 | + */ | |
166 | + public boolean renameTo(FileOperation dest); | |
167 | + | |
168 | + /** | |
169 | + * 親のディレクトリを返します。 | |
170 | + * | |
171 | + * @return 親のディレクトリ | |
172 | + */ | |
173 | + public FileOperation getParentFile(); | |
174 | + | |
175 | + /** | |
176 | + * 書き込み可能フラグ | |
177 | + * | |
178 | + * ※クラウドストレージの場合は、 | |
179 | + * 必ずtrueを返します。 | |
180 | + * | |
181 | + * @return 書き込み可能フラグ | |
182 | + */ | |
183 | + public boolean canWrite(); | |
184 | + | |
185 | + /** | |
186 | + * 読み取り可能フラグ | |
187 | + * | |
188 | + * ※クラウドストレージの場合は、 | |
189 | + * 必ずtrueを返します。 | |
190 | + * | |
191 | + * @return 読み取り可能フラグ | |
192 | + */ | |
193 | + public boolean canRead(); | |
194 | + | |
195 | + /** | |
196 | + * 隠しファイルフラグ | |
197 | + * | |
198 | + * ※クラウドストレージの場合は、 | |
199 | + * 必ずfalseを返します。 | |
200 | + * | |
201 | + * @return 隠しファイルフラグ | |
202 | + */ | |
203 | + public boolean isHidden(); | |
204 | + | |
205 | + /** | |
206 | + * 新規ファイル作成 | |
207 | + * | |
208 | + * 既にファイルが存在しない場合のみ、 | |
209 | + * 空のファイルを作成します。 | |
210 | + * | |
211 | + * @return 成否フラグ | |
212 | + * @throws IOException | |
213 | + */ | |
214 | + public boolean createNewFile() throws IOException; | |
215 | + | |
216 | + /** | |
217 | + * 最終更新時刻の更新 | |
218 | + * | |
219 | + * 最終更新時刻の更新を行います。 | |
220 | + * ※クラウドストレージの場合は、 | |
221 | + * 最終更新時刻の更新を行えません。 | |
222 | + * | |
223 | + * @param time 更新する最終更新時刻 | |
224 | + * @return 成否フラグ | |
225 | + */ | |
226 | + public boolean setLastModified(long time); | |
227 | + | |
228 | + /** | |
229 | + * カノニカルファイル情報を取得します。 | |
230 | + * | |
231 | + * ※ローカルサーバのみ通常ファイルと、 | |
232 | + * カノニカルファイルで異なります。 | |
233 | + * | |
234 | + * @return カノニカルファイル情報 | |
235 | + * @throws IOException | |
236 | + */ | |
237 | + public FileOperation getCanonicalFile() throws IOException; | |
238 | +} | |
\ No newline at end of file |
@@ -0,0 +1,106 @@ | ||
1 | +package org.opengion.fukurou.model; | |
2 | + | |
3 | +import java.io.File; | |
4 | + | |
5 | +import org.opengion.fukurou.util.StringUtil; | |
6 | + | |
7 | + | |
8 | +/** | |
9 | + * ファイル操作インスタンスのファクトリークラス | |
10 | + * | |
11 | + * システムリソースの「CLOUD_TARGET」を参照して、 | |
12 | + * 処理対象のファイル操作クラスを生成します。 | |
13 | + * | |
14 | + * デフォルトはローカルサーバのファイル操作を行う、 | |
15 | + * DefaultFileOperationクラスを生成します。 | |
16 | + * | |
17 | + * @og.rev 5.10.8.0 (2019/02/01) 新規作成 | |
18 | + * @sinse JDK7.0 | |
19 | + */ | |
20 | +public class FileOperationFactory { | |
21 | + private static final int BUFFER_MIDDLE = 200; | |
22 | + | |
23 | + /** | |
24 | + * 引数を元に、ファイル操作クラスを生成します。 | |
25 | + * | |
26 | + * @param path ファイルパス | |
27 | + * @return ファイル操作インスタンス | |
28 | + */ | |
29 | + public static FileOperation newStorageOperation(String path) { | |
30 | + return newStorageOperation(null,path.toString()); | |
31 | + } | |
32 | + | |
33 | + /** | |
34 | + * 引数を元に、ファイル操作クラスを生成します。 | |
35 | + * | |
36 | + * @param plugin 利用プラグイン | |
37 | + * @param dir ディレクトリ | |
38 | + * @param fileName ファイル名 | |
39 | + * @return ファイル操作インスタンス | |
40 | + */ | |
41 | + public static FileOperation newStorageOperation(String plugin, String dir, String fileName) { | |
42 | + StringBuilder path = new StringBuilder(BUFFER_MIDDLE); | |
43 | + path.append(dir).append(File.separator).append(fileName); | |
44 | + | |
45 | + return newStorageOperation(path.toString()); | |
46 | + } | |
47 | + | |
48 | + /** | |
49 | + * 引数を元に、ファイル操作クラスを生成します。 | |
50 | + * | |
51 | + * @param plugin 利用プラグイン | |
52 | + * @param file ファイル情報 | |
53 | + * @param fileName ファイル名 | |
54 | + * @return ファイル操作インスタンス | |
55 | + */ | |
56 | + public static FileOperation newStorageOperation(String plugin, FileOperation file, String fileName) { | |
57 | + StringBuilder path = new StringBuilder(BUFFER_MIDDLE); | |
58 | + path.append(file.getPath()).append(File.separator).append(fileName); | |
59 | + | |
60 | + return newStorageOperation(path.toString()); | |
61 | + } | |
62 | + | |
63 | + /** | |
64 | + * 引数を元に、ファイル操作クラスを生成します。 | |
65 | + * CLOUD_TARGETがNULLの場合はローカルファイル用のクラスを利用します。 | |
66 | + * | |
67 | + * @param plugin 利用プラグイン | |
68 | + * @param path ファイルパス | |
69 | + * @return ファイル操作インスタンス | |
70 | + */ | |
71 | + public static FileOperation newStorageOperation(String plugin, String path) { | |
72 | + FileOperation rtn; | |
73 | + String cloudTarget = null; | |
74 | + | |
75 | + Object[] args = new Object[] { path }; | |
76 | + | |
77 | + // 対象のクラウドサービスを取得(大文字化)。 | |
78 | + // 未指定の場合は、ローカルディレクトリを利用。 | |
79 | + if ( plugin != null && plugin.length() > 0 ) { | |
80 | + cloudTarget = plugin.toUpperCase(); | |
81 | + } | |
82 | + | |
83 | + try { | |
84 | + StringBuilder sb = new StringBuilder(BUFFER_MIDDLE); | |
85 | + | |
86 | + if (StringUtil.isNull(cloudTarget)) { | |
87 | + sb.append("org.opengion.fukurou.model.DefaultFileOperation"); | |
88 | + } else { | |
89 | + sb.append("org.opengion.plugin.cloud."); | |
90 | + sb.append("FileOperation_"); | |
91 | + sb.append(cloudTarget); | |
92 | + } | |
93 | + | |
94 | + rtn = (FileOperation) Class.forName(sb.toString()) | |
95 | + .getConstructor(String.class) | |
96 | + .newInstance(args); | |
97 | + } catch (Exception e) { | |
98 | + StringBuilder errMsg = new StringBuilder(BUFFER_MIDDLE); | |
99 | + errMsg.append("ファイルストレージの操作クラス生成に失敗しました。target:").append(cloudTarget); | |
100 | + errMsg.append(" システムエラー情報:").append(e.getMessage()); | |
101 | + throw new RuntimeException(errMsg.toString()); | |
102 | + } | |
103 | + | |
104 | + return rtn; | |
105 | + } | |
106 | +} |
@@ -0,0 +1,23 @@ | ||
1 | +package org.opengion.fukurou.model; | |
2 | + | |
3 | +/** | |
4 | + * ファイル情報のフィルタインタフェースです。 | |
5 | + * | |
6 | + * java.io.FileFilterの、 | |
7 | + * acceptの引数を、 | |
8 | + * java.io.Fileから、FileOperationInfoに変更した実装です。 | |
9 | + * | |
10 | + * @og.group ファイル操作 | |
11 | + * | |
12 | + * @og.rev 5.10.8.0 (2019/02/01) 新規作成 | |
13 | + * @author oota | |
14 | + * @since JDK7 | |
15 | + * | |
16 | + */ | |
17 | +public interface FileOperationFileFilter { | |
18 | + /** | |
19 | + * @param info | |
20 | + * @return accept | |
21 | + */ | |
22 | + boolean accept(FileOperationInfo info); | |
23 | +} |
@@ -0,0 +1,191 @@ | ||
1 | +package org.opengion.fukurou.model; | |
2 | + | |
3 | +/** | |
4 | + * ファイル情報の格納クラス | |
5 | + * | |
6 | + * listFilesで取得した、 | |
7 | + * ディレクトリとファイル一覧情報の格納用クラスです。 | |
8 | + * | |
9 | + * @og.group ファイル操作 | |
10 | + * | |
11 | + * @og.rev 5.10.8.0 (2019/02/01) 新規作成 | |
12 | + * @author oota | |
13 | + * @since JDK7.0 | |
14 | + */ | |
15 | +public class FileOperationInfo extends AbstractFileOperation | |
16 | + implements Comparable<FileOperation> { | |
17 | + /** クラス変数 */ | |
18 | + private String path; | |
19 | + private String name; | |
20 | + private String parent; | |
21 | + private long size; | |
22 | + private long lastModified; | |
23 | + private boolean isFile; | |
24 | + private boolean isDirectory; | |
25 | + private boolean isHidden; | |
26 | + private boolean canRead; | |
27 | + private boolean canWrite; | |
28 | + | |
29 | + /** | |
30 | + * コンストラクタ | |
31 | + */ | |
32 | + public FileOperationInfo() { | |
33 | + // クラス変数の初期化 | |
34 | + path = ""; | |
35 | + name = ""; | |
36 | + parent = ""; | |
37 | + size = 0; | |
38 | + lastModified = 0; | |
39 | + isFile = false; | |
40 | + isDirectory = false; | |
41 | + isHidden = false; | |
42 | + canRead = true; | |
43 | + canWrite = true; | |
44 | + } | |
45 | + | |
46 | + /** Getter ・ Setter */ | |
47 | + @Override | |
48 | + public String getPath() { | |
49 | + return path; | |
50 | + } | |
51 | + | |
52 | + /** | |
53 | + * @param path | |
54 | + */ | |
55 | + public void setPath(String path) { | |
56 | + this.path = path; | |
57 | + } | |
58 | + | |
59 | + @Override | |
60 | + public String getName() { | |
61 | + return name; | |
62 | + } | |
63 | + | |
64 | + /** | |
65 | + * @param name | |
66 | + */ | |
67 | + public void setName(String name) { | |
68 | + this.name = name; | |
69 | + } | |
70 | + | |
71 | + @Override | |
72 | + public String getParent() { | |
73 | + return parent; | |
74 | + } | |
75 | + | |
76 | + /** | |
77 | + * @param parent | |
78 | + */ | |
79 | + public void setParent(String parent) { | |
80 | + this.parent = parent; | |
81 | + } | |
82 | + | |
83 | + @Override | |
84 | + public long length() { | |
85 | + return size; | |
86 | + } | |
87 | + | |
88 | + /** | |
89 | + * @param size | |
90 | + */ | |
91 | + public void setSize(long size) { | |
92 | + this.size = size; | |
93 | + } | |
94 | + | |
95 | + @Override | |
96 | + public long lastModified() { | |
97 | + return lastModified; | |
98 | + } | |
99 | + | |
100 | + /** | |
101 | + * @param lastModified | |
102 | + */ | |
103 | + public void setLastModifiedValue(long lastModified) { | |
104 | + this.lastModified = lastModified; | |
105 | + } | |
106 | + | |
107 | + @Override | |
108 | + public boolean isFile() { | |
109 | + return isFile; | |
110 | + } | |
111 | + | |
112 | + /** | |
113 | + * @param isFile | |
114 | + */ | |
115 | + public void setFile(boolean isFile) { | |
116 | + this.isFile = isFile; | |
117 | + } | |
118 | + | |
119 | + @Override | |
120 | + public boolean isDirectory() { | |
121 | + return isDirectory; | |
122 | + } | |
123 | + | |
124 | + /** | |
125 | + * @param isDirectory | |
126 | + */ | |
127 | + public void setDirectory(boolean isDirectory) { | |
128 | + this.isDirectory = isDirectory; | |
129 | + } | |
130 | + | |
131 | + @Override | |
132 | + public boolean isHidden() { | |
133 | + return isHidden; | |
134 | + } | |
135 | + | |
136 | + /** | |
137 | + * @param isHidden | |
138 | + */ | |
139 | + public void setHidden(boolean isHidden) { | |
140 | + this.isHidden = isHidden; | |
141 | + } | |
142 | + | |
143 | + @Override | |
144 | + public boolean canRead() { | |
145 | + return canRead; | |
146 | + } | |
147 | + | |
148 | + /** | |
149 | + * @param canRead | |
150 | + */ | |
151 | + public void setCanRead(boolean canRead) { | |
152 | + this.canRead = canRead; | |
153 | + } | |
154 | + | |
155 | + @Override | |
156 | + public boolean canWrite() { | |
157 | + return canWrite; | |
158 | + } | |
159 | + | |
160 | + /** | |
161 | + * @param canWrite | |
162 | + */ | |
163 | + public void setCanWrite(boolean canWrite) { | |
164 | + this.canWrite = canWrite; | |
165 | + } | |
166 | + | |
167 | + /** | |
168 | + * 1つ下の、ディレクトリ・ファイル一覧を取得します。 | |
169 | + */ | |
170 | + @Override | |
171 | + public FileOperation[] listFiles(FileOperationFileFilter filter) { | |
172 | + FileOperation file = FileOperationFactory.newStorageOperation(path); | |
173 | + return file.listFiles(filter); | |
174 | + } | |
175 | + | |
176 | + /** | |
177 | + * compareToでは、パスの比較を行います。 | |
178 | + */ | |
179 | + @Override | |
180 | + public int compareTo(FileOperation trg) { | |
181 | + return getPath().compareToIgnoreCase(trg.getPath()); | |
182 | + } | |
183 | + | |
184 | + /** | |
185 | + * カノニカルファイル取得メソッドでは、自身を返します。 | |
186 | + */ | |
187 | + @Override | |
188 | + public FileOperation getCanonicalFile() { | |
189 | + return this; | |
190 | + } | |
191 | +} |
@@ -17,14 +17,16 @@ | ||
17 | 17 | |
18 | 18 | import java.io.File; |
19 | 19 | import java.io.FileFilter; |
20 | -import java.util.List; | |
21 | 20 | import java.util.ArrayList; |
22 | 21 | import java.util.Calendar; |
22 | +import java.util.List; | |
23 | 23 | import java.util.StringTokenizer; |
24 | - | |
24 | +import java.util.regex.Matcher; | |
25 | 25 | import java.util.regex.Pattern; |
26 | -import java.util.regex.Matcher; | |
27 | 26 | |
27 | +import org.opengion.fukurou.model.FileOperationFileFilter; | |
28 | +import org.opengion.fukurou.model.FileOperationInfo; | |
29 | + | |
28 | 30 | /** |
29 | 31 | * HybsFileFilter.java は、複数の FileFilter を順次実行する フィルタクラスです。 |
30 | 32 | * |
@@ -32,6 +34,9 @@ | ||
32 | 34 | * 渡すことができます。 |
33 | 35 | * Filterに設定された複数のフィルタすべてを満たす場合の時のみ、accept(File pathname) |
34 | 36 | * メソッドは、true を返します。 |
37 | + * | |
38 | + * FileOperationFileFilterインターフェースも継承しており、こちらはopenGionで実装している | |
39 | + * FileOperationを扱う事が可能です。 | |
35 | 40 | * |
36 | 41 | * この実装は同期化されません。 |
37 | 42 | * |
@@ -38,9 +43,16 @@ | ||
38 | 43 | * @version 4.0 |
39 | 44 | * @author Kazuhiko Hasegawa |
40 | 45 | * @since JDK5.0, |
46 | + * | |
47 | + * @og.rev 5.10.8.0 (2019/02/01) FileOperationFileFilterでのフィルタ処理対応 | |
48 | + * | |
41 | 49 | */ |
42 | -public final class HybsFileFilter implements FileFilter { | |
50 | +// 5.10.8.0 (2019/02/01) implementsにFileOperationFileFilterを追加 | |
51 | +// public final class HybsFileFilter implements FileFilter { | |
52 | +public final class HybsFileFilter implements FileFilter, FileOperationFileFilter { | |
43 | 53 | private final List<FileFilter> list = new ArrayList<FileFilter>(); |
54 | + // 5.10.8.0 (2019/02/01) ofList追加(FileOperationFileFilter用のリスト) | |
55 | + private final List<FileOperationFileFilter> foList = new ArrayList<FileOperationFileFilter>(); | |
44 | 56 | private final boolean isUseDIR ; |
45 | 57 | |
46 | 58 | /** |
@@ -90,6 +102,30 @@ | ||
90 | 102 | } |
91 | 103 | return true; |
92 | 104 | } |
105 | + | |
106 | + /** | |
107 | + * 指定された抽象パス名がパス名リストに含まれる必要がある場合、スルー(選択)されます。 | |
108 | + * ここでの判定ロジックでは、ファイルについてのみ処理します。 | |
109 | + * ディレクトリは、常に、true を返します。 | |
110 | + * 5.10.8.0 (2019/02/01) ADD | |
111 | + * | |
112 | + * @param exFileInfo 拡張ファイルオブジェクト | |
113 | + * | |
114 | + * @return パス名リストに含まれるかどうか | |
115 | + * @see org.opengion.fukurou.model.FileOperationFileFilter#accept(FileOperationInfo) | |
116 | + */ | |
117 | + public boolean accept( final FileOperationInfo exFileInfo) { | |
118 | + if( exFileInfo != null && (exFileInfo.isFile() || isUseDIR) ) { | |
119 | + int size = foList.size(); | |
120 | + for( int i=0; i<size; i++ ) { | |
121 | + FileOperationFileFilter filter = foList.get(i); | |
122 | + if( !filter.accept( exFileInfo ) ) { | |
123 | + return false; | |
124 | + } | |
125 | + } | |
126 | + } | |
127 | + return true; | |
128 | + } | |
93 | 129 | |
94 | 130 | /** |
95 | 131 | * 外部指定フィルタ: 内部判定条件に、フィルタを追加します。 |
@@ -102,6 +138,16 @@ | ||
102 | 138 | } |
103 | 139 | |
104 | 140 | /** |
141 | + * 外部指定フィルタ: 内部判定条件に、フィルタを追加します。 | |
142 | + * 引数が null の場合は、追加しません。 | |
143 | + * | |
144 | + * @param exFilter 拡張外部指定フィルタ | |
145 | + */ | |
146 | + public void addFileFilter( final FileOperationFileFilter exFilter ) { | |
147 | + if( exFilter != null ) { foList.add( exFilter ); } | |
148 | + } | |
149 | + | |
150 | + /** | |
105 | 151 | * 内部判定フィルタ: 指定された接頭辞で始まる場合、スルー(選択)されます。 |
106 | 152 | * 引数が null の場合は、追加しません。 |
107 | 153 | * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。 |
@@ -130,7 +176,11 @@ | ||
130 | 176 | */ |
131 | 177 | public void startsWith( final String prefix,final boolean reverse ) { |
132 | 178 | if( prefix != null ) { |
133 | - list.add( new StartsWithFilter( prefix,reverse ) ); | |
179 | + // 5.10.8.0 (2019/02/01) MOD 追加した拡張リストにも追加するように変更 | |
180 | + // list.add( new StartsWithFilter( prefix,reverse ) ); | |
181 | + StartsWithFilter filter = new StartsWithFilter( prefix,reverse ); | |
182 | + list.add(filter); | |
183 | + foList.add(filter); | |
134 | 184 | } |
135 | 185 | } |
136 | 186 |
@@ -144,7 +194,9 @@ | ||
144 | 194 | * @author Kazuhiko Hasegawa |
145 | 195 | * @since JDK5.0, |
146 | 196 | */ |
147 | - private static class StartsWithFilter implements FileFilter { | |
197 | + // 5.10.8.0 (2019/02/01) MOD implementsにFileOperationFileFilterを追加 | |
198 | +// private static class StartsWithFilter implements FileFilter | |
199 | + private static class StartsWithFilter implements FileFilter, FileOperationFileFilter { | |
148 | 200 | // private final String pfix ; |
149 | 201 | private final String[] pfix ; |
150 | 202 | private final int cnt ; |
@@ -153,7 +205,7 @@ | ||
153 | 205 | /** |
154 | 206 | * 接頭辞フィルターオブジェクトを作成します。 |
155 | 207 | * |
156 | - * @param desc true:昇順 / false:降順 | |
208 | + * @param prefix 接頭辞 | |
157 | 209 | * @param reverse true:結果を反転する |
158 | 210 | */ |
159 | 211 | StartsWithFilter( final String prefix,final boolean reverse ) { |
@@ -187,6 +239,23 @@ | ||
187 | 239 | } |
188 | 240 | return rvse; |
189 | 241 | } |
242 | + | |
243 | + /** | |
244 | + * FileFilter インターフェースの accept( FileOperationInfo ) メソッド | |
245 | + * 5.10.8.0 (2019/02/01) ADD | |
246 | + * | |
247 | + * @param exFileInfo 拡張ファイルオブジェクト | |
248 | + * @return true:処理対象 / false:処理非対象 | |
249 | + * @see org.opengion.fukurou.model.FileOperationFileFilter#accept(FileOperationInfo) | |
250 | + */ | |
251 | + public boolean accept( final FileOperationInfo exFileInfo) { | |
252 | + for( int i=0; i<cnt; i++ ) { | |
253 | + if (exFileInfo.getName().startsWith( pfix[i] ) ) { | |
254 | + return !rvse; | |
255 | + } | |
256 | + } | |
257 | + return rvse; | |
258 | + } | |
190 | 259 | } |
191 | 260 | |
192 | 261 | /** |
@@ -218,12 +287,17 @@ | ||
218 | 287 | */ |
219 | 288 | public void endsWith( final String suffix,final boolean reverse ) { |
220 | 289 | if( suffix != null ) { |
221 | - list.add( new EndsWithFilter( suffix,reverse ) ); | |
290 | + // 5.10.8.0 (2019/02/01) MOD | |
291 | + // 拡張ファイルリストにも追加するように変更 | |
292 | + // list.add( new EndsWithFilter( suffix,reverse ) ); | |
293 | + EndsWithFilter filter = new EndsWithFilter( suffix,reverse ); | |
294 | + list.add(filter); | |
295 | + foList.add(filter); | |
222 | 296 | } |
223 | 297 | } |
224 | 298 | |
225 | 299 | /** |
226 | - * 指定された接頭辞で終わる場合に選択される FileFilter インターフェースの実装内部クラスです。 | |
300 | + * 指定された接尾辞で終わる場合に選択される FileFilter インターフェースの実装内部クラスです。 | |
227 | 301 | * 引数に、'|' 区切り文字で複数設定した場合は、OR 判断(どれかが一致)します。 |
228 | 302 | * |
229 | 303 | * @og.rev 5.1.2.0 (2010/01/01) '|' 区切り文字で複数設定処理の追加、reverse属性の追加 |
@@ -232,7 +306,9 @@ | ||
232 | 306 | * @author Kazuhiko Hasegawa |
233 | 307 | * @since JDK5.0, |
234 | 308 | */ |
235 | - private static class EndsWithFilter implements FileFilter { | |
309 | + // 5.10.8.0 (2019/02/01) MOD implementsにFileOperationFileFilterを追加 | |
310 | +// private static class EndsWithFilter implements FileFilter | |
311 | + private static class EndsWithFilter implements FileFilter, FileOperationFileFilter { | |
236 | 312 | // private final String sfix ; |
237 | 313 | private final String[] sfix ; |
238 | 314 | private final int cnt ; |
@@ -241,7 +317,7 @@ | ||
241 | 317 | /** |
242 | 318 | * 接頭辞フィルターオブジェクトを作成します。 |
243 | 319 | * |
244 | - * @param desc true:昇順 / false:降順 | |
320 | + * @param suffix 接尾辞 | |
245 | 321 | * @param reverse true:結果を反転する |
246 | 322 | */ |
247 | 323 | EndsWithFilter( final String suffix,final boolean reverse ) { |
@@ -275,6 +351,23 @@ | ||
275 | 351 | } |
276 | 352 | return rvse; |
277 | 353 | } |
354 | + | |
355 | + /** | |
356 | + * FileFilter インターフェースの accept( FileOperationInfo ) メソッド | |
357 | + * 5.10.8.0 (2019/02/01) ADD | |
358 | + * | |
359 | + * @param exFileInfo 拡張ファイルオブジェクト | |
360 | + * @return true:処理対象 / false:処理非対象 | |
361 | + * @see org.opengion.fukurou.model.FileOperationFileFilter#accept(FileOperationInfo) | |
362 | + */ | |
363 | + public boolean accept( final FileOperationInfo exFileInfo ) { | |
364 | + for( int i=0; i<cnt; i++ ){ | |
365 | + if( exFileInfo.getName().endsWith( sfix[i] ) ) { | |
366 | + return !rvse; | |
367 | + } | |
368 | + } | |
369 | + return rvse; | |
370 | + } | |
278 | 371 | } |
279 | 372 | |
280 | 373 | /** |
@@ -304,7 +397,12 @@ | ||
304 | 397 | */ |
305 | 398 | public void instr( final String str,final boolean reverse ) { |
306 | 399 | if( str != null ) { |
307 | - list.add( new InstrFilter( str,reverse ) ); | |
400 | + // 5.10.8.0 (2019/02/01) MOD | |
401 | + // 拡張ファイルリストにも追加するように変更 | |
402 | + // list.add( new InstrFilter( str,reverse ) ); | |
403 | + InstrFilter filter = new InstrFilter( str,reverse ); | |
404 | + list.add(filter); | |
405 | + foList.add(filter); | |
308 | 406 | } |
309 | 407 | } |
310 | 408 |
@@ -318,7 +416,9 @@ | ||
318 | 416 | * @author Kazuhiko Hasegawa |
319 | 417 | * @since JDK5.0, |
320 | 418 | */ |
321 | - private static class InstrFilter implements FileFilter { | |
419 | + // 5.10.8.0 (2019/02/01) MOD implementsにFileOperationFileFilterを追加 | |
420 | +// private static class InstrFilter implements FileFilter{ | |
421 | + private static class InstrFilter implements FileFilter, FileOperationFileFilter { | |
322 | 422 | // private final String instr ; |
323 | 423 | private final String[] instr ; |
324 | 424 | private final int cnt ; |
@@ -327,7 +427,7 @@ | ||
327 | 427 | /** |
328 | 428 | * 文字列包含フィルターオブジェクトを作成します。 |
329 | 429 | * |
330 | - * @param desc true:昇順 / false:降順 | |
430 | + * @param str ファイル名文字列 | |
331 | 431 | * @param reverse true:結果を反転する |
332 | 432 | */ |
333 | 433 | InstrFilter( final String str,final boolean reverse ) { |
@@ -361,6 +461,23 @@ | ||
361 | 461 | } |
362 | 462 | return rvse; |
363 | 463 | } |
464 | + | |
465 | + /** | |
466 | + * FileFilter インターフェースの accept( FileOperationInfo ) メソッド | |
467 | + * 5.10.8.0 (2019/02/01) ADD | |
468 | + * | |
469 | + * @param exFileInfo ファイルオブジェクト | |
470 | + * @return true:処理対象 / false:処理非対象 | |
471 | + * @see org.opengion.fukurou.model.FileOperationFileFilter#accept(FileOperationInfo) | |
472 | + */ | |
473 | + public boolean accept( final FileOperationInfo exFileInfo) { | |
474 | + for( int i=0; i<cnt; i++ ) { | |
475 | + if( exFileInfo.getName().indexOf( instr[i] ) >= 0 ) { | |
476 | + return !rvse; | |
477 | + } | |
478 | + } | |
479 | + return rvse; | |
480 | + } | |
364 | 481 | } |
365 | 482 | |
366 | 483 | /** |
@@ -392,7 +509,12 @@ | ||
392 | 509 | */ |
393 | 510 | public void fileEquals( final String str,final boolean reverse ) { |
394 | 511 | if( str != null ) { |
395 | - list.add( new EqualsFilter( str,reverse ) ); | |
512 | + // 5.10.8.0 (2019/02/01) MOD | |
513 | + // 拡張ファイルリストにも追加するように変更 | |
514 | + // list.add( new EqualsFilter( str,reverse ) ); | |
515 | + EqualsFilter filter = new EqualsFilter( str,reverse ); | |
516 | + list.add(filter); | |
517 | + foList.add(filter); | |
396 | 518 | } |
397 | 519 | } |
398 | 520 |
@@ -406,7 +528,9 @@ | ||
406 | 528 | * @author Kazuhiko Hasegawa |
407 | 529 | * @since JDK5.0, |
408 | 530 | */ |
409 | - private static class EqualsFilter implements FileFilter { | |
531 | + // 5.10.8.0 (2019/02/01) MOD implementsにFileOperationFileFilterを追加 | |
532 | +// private static class EqualsFilter implements FileFilter { | |
533 | + private static class EqualsFilter implements FileFilter, FileOperationFileFilter { | |
410 | 534 | // private final String eqstr ; |
411 | 535 | private final String[] eqstr ; |
412 | 536 | private final int cnt ; |
@@ -415,7 +539,7 @@ | ||
415 | 539 | /** |
416 | 540 | * ファイル名一致フィルターオブジェクトを作成します。 |
417 | 541 | * |
418 | - * @param desc true:昇順 / false:降順 | |
542 | + * @param str ファイル名 | |
419 | 543 | * @param reverse true:結果を反転する |
420 | 544 | */ |
421 | 545 | EqualsFilter( final String str,final boolean reverse ) { |
@@ -449,6 +573,22 @@ | ||
449 | 573 | } |
450 | 574 | return rvse; |
451 | 575 | } |
576 | + | |
577 | + /** | |
578 | + * FileFilter インターフェースの accept( FileOperationInfo ) メソッド | |
579 | + * | |
580 | + * @param exFileInfo 拡張ファイルオブジェクト | |
581 | + * @return true:処理対象 / false:処理非対象 | |
582 | + * @see org.opengion.fukurou.model.FileOperationFileFilter#accept(FileOperationInfo) | |
583 | + */ | |
584 | + public boolean accept( final FileOperationInfo exFileInfo) { | |
585 | + for( int i=0; i<cnt; i++ ) { | |
586 | + if( exFileInfo.getName().equalsIgnoreCase( eqstr[i] ) ) { | |
587 | + return !rvse; | |
588 | + } | |
589 | + } | |
590 | + return rvse; | |
591 | + } | |
452 | 592 | } |
453 | 593 | |
454 | 594 | /** |
@@ -490,7 +630,12 @@ | ||
490 | 630 | */ |
491 | 631 | public void matches( final String str,final boolean reverse ) { |
492 | 632 | if( str != null ) { |
493 | - list.add( new MatchesFilter( str,reverse ) ); | |
633 | + // 5.10.8.0 (2019/02/01) MOD | |
634 | + // 拡張ファイルリストにも追加するように変更 | |
635 | + // list.add( new MatchesFilter( str,reverse ) ); | |
636 | + MatchesFilter filter = new MatchesFilter( str,reverse ); | |
637 | + list.add(filter); | |
638 | + foList.add(filter); | |
494 | 639 | } |
495 | 640 | } |
496 | 641 |
@@ -503,7 +648,9 @@ | ||
503 | 648 | * @author Kazuhiko Hasegawa |
504 | 649 | * @since JDK5.0, |
505 | 650 | */ |
506 | - private static class MatchesFilter implements FileFilter { | |
651 | + // 5.10.8.0 (2019/02/01) MOD implementsにFileOperationFileFilterを追加 | |
652 | +// private static class MatchesFilter implements FileFilter { | |
653 | + private static class MatchesFilter implements FileFilter, FileOperationFileFilter { | |
507 | 654 | private final Pattern pattern ; |
508 | 655 | private final boolean rvse ; |
509 | 656 |
@@ -510,7 +657,7 @@ | ||
510 | 657 | /** |
511 | 658 | * 正規表現一致フィルターオブジェクトを作成します。 |
512 | 659 | * |
513 | - * @param desc true:昇順 / false:降順 | |
660 | + * @param str ファイル名文字列(正規表現) とマッチしない | |
514 | 661 | * @param reverse true:結果を反転する |
515 | 662 | */ |
516 | 663 | MatchesFilter( final String str,final boolean reverse ) { |
@@ -531,6 +678,19 @@ | ||
531 | 678 | if( match.find() ) { return !rvse; } |
532 | 679 | else { return rvse; } |
533 | 680 | } |
681 | + | |
682 | + /** | |
683 | + * FileOperationFileFilter インターフェースの accept( File ) メソッド | |
684 | + * | |
685 | + * @param exFileInfo fileOperationオブジェクト | |
686 | + * @return true:処理対象 / false:処理非対象 | |
687 | + * @see org.opengion.fukurou.model.FileOperationFileFilter#accept(FileOperationInfo) | |
688 | + */ | |
689 | + public boolean accept( final FileOperationInfo exFileInfo) { | |
690 | + Matcher match = pattern.matcher( exFileInfo.getName() ); | |
691 | + if( match.find() ) { return !rvse; } | |
692 | + else { return rvse; } | |
693 | + } | |
534 | 694 | } |
535 | 695 | |
536 | 696 | /** |
@@ -596,7 +756,11 @@ | ||
596 | 756 | */ |
597 | 757 | public void lastModified( final String modify ) { |
598 | 758 | if( modify != null ) { |
599 | - list.add( new ModifyFileFilter( modify ) ); | |
759 | + // 5.10.8.0 (2019/02/01) MOD 拡張ファイルリストにも追加するように変更 | |
760 | +// list.add( new ModifyFileFilter( modify ) ); | |
761 | + ModifyFileFilter filter = new ModifyFileFilter( modify ); | |
762 | + list.add(filter); | |
763 | + foList.add(filter); | |
600 | 764 | } |
601 | 765 | } |
602 | 766 |
@@ -671,7 +835,11 @@ | ||
671 | 835 | long len = getByteSize( slen ); |
672 | 836 | |
673 | 837 | if( len >= 0L ) { |
674 | - list.add( new IsLargerFilter( len ) ); | |
838 | + // 5.10.8.0 (2019/02/01) MOD 拡張ファイルリストにも追加するように変更 | |
839 | + // list.add( new IsLargerFilter( len ) ); | |
840 | + IsLargerFilter filter = new IsLargerFilter( len ); | |
841 | + list.add( filter ); | |
842 | + foList.add( filter ); | |
675 | 843 | } |
676 | 844 | } |
677 | 845 |
@@ -682,7 +850,9 @@ | ||
682 | 850 | * @author Kazuhiko Hasegawa |
683 | 851 | * @since JDK5.0, |
684 | 852 | */ |
685 | - private static class IsLargerFilter implements FileFilter { | |
853 | + // 5.10.8.0 (2019/02/01) MOD implementsにFileOperationFileFilterを追加 | |
854 | +// private static class IsLargerFilter implements FileFilter | |
855 | + private static class IsLargerFilter implements FileFilter, FileOperationFileFilter { | |
686 | 856 | private final long size ; |
687 | 857 | |
688 | 858 | /** |
@@ -707,6 +877,17 @@ | ||
707 | 877 | public boolean accept( final File pathname ) { |
708 | 878 | return pathname.length() >= size; |
709 | 879 | } |
880 | + | |
881 | + /** | |
882 | + * FileOperationFileFilter インターフェースの accept( FileOperationInfo ) メソッド | |
883 | + * | |
884 | + * @param exFileInfo 拡張ファイルオブジェクト | |
885 | + * @return true:処理対象 / false:処理非対象 | |
886 | + * @see org.opengion.fukurou.model.FileOperationFileFilter#accept(FileOperationInfo) | |
887 | + */ | |
888 | + public boolean accept( final FileOperationInfo exFileInfo ) { | |
889 | + return exFileInfo.length() >= size; | |
890 | + } | |
710 | 891 | } |
711 | 892 | |
712 | 893 | /** |
@@ -737,7 +918,9 @@ | ||
737 | 918 | * @author Kazuhiko Hasegawa |
738 | 919 | * @since JDK5.0, |
739 | 920 | */ |
740 | - private static class IsSmallerFilter implements FileFilter { | |
921 | + // 5.10.8.0 (2019/02/01) MOD implementsにFileOperationFileFilterを追加 | |
922 | +// private static class IsSmallerFilter implements FileFilter { | |
923 | + private static class IsSmallerFilter implements FileFilter, FileOperationFileFilter { | |
741 | 924 | private final long size ; |
742 | 925 | |
743 | 926 | /** |
@@ -762,6 +945,17 @@ | ||
762 | 945 | public boolean accept( final File pathname ) { |
763 | 946 | return pathname.length() < size; |
764 | 947 | } |
948 | + | |
949 | + /** | |
950 | + * FileOperationFileFilter インターフェースの accept( FileOperationInfo ) メソッド | |
951 | + * | |
952 | + * @param exFileInfo 拡張ファイルオブジェクト | |
953 | + * @return true:処理対象 / false:処理非対象 | |
954 | + * @see org.opengion.fukurou.model.FileOperationFileFilter#accept(FileOperationInfo) | |
955 | + */ | |
956 | + public boolean accept( final FileOperationInfo exFileInfo) { | |
957 | + return exFileInfo.length() < size; | |
958 | + } | |
765 | 959 | } |
766 | 960 | |
767 | 961 | /** |
@@ -793,7 +987,11 @@ | ||
793 | 987 | */ |
794 | 988 | public void isHidden( final String flag,final boolean reverse ) { |
795 | 989 | if( flag != null ) { |
796 | - list.add( new IsHiddenFilter( flag,reverse ) ); | |
990 | + // 5.10.8.0 (2019/02/01) MOD 拡張ファイルリストにも追加するように変更 | |
991 | + // list.add( new IsHiddenFilter( flag,reverse ) ); | |
992 | + IsHiddenFilter filter = new IsHiddenFilter( flag, reverse ); | |
993 | + list.add(filter); | |
994 | + foList.add(filter); | |
797 | 995 | } |
798 | 996 | } |
799 | 997 |
@@ -809,7 +1007,9 @@ | ||
809 | 1007 | * @author Kazuhiko Hasegawa |
810 | 1008 | * @since JDK6.0, |
811 | 1009 | */ |
812 | - private static class IsHiddenFilter implements FileFilter { | |
1010 | + // 5.10.8.0 (2019/02/01) MOD implementsにFileOperationFileFilterを追加 | |
1011 | +// private static class IsHiddenFilter implements FileFilter { | |
1012 | + private static class IsHiddenFilter implements FileFilter, FileOperationFileFilter { | |
813 | 1013 | private final boolean flg ; |
814 | 1014 | private final boolean rvse ; |
815 | 1015 |
@@ -845,6 +1045,18 @@ | ||
845 | 1045 | // false(normal) true false true ⇒ true 選択 |
846 | 1046 | // false(normal) false true true ⇒ false 除外 |
847 | 1047 | } |
1048 | + | |
1049 | + /** | |
1050 | + * FileOperationFileFilter インターフェースの accept( FileOperationInfo ) メソッド | |
1051 | + * 5.10.8.0 (2019/02/01) ADD | |
1052 | + * | |
1053 | + * @param exFileInfo 拡張ファイルオブジェクト | |
1054 | + * @return true:処理対象 / false:処理非対象 | |
1055 | + * @see org.opengion.fukurou.model.FileOperationFileFilter#accept(FileOperationInfo) | |
1056 | + */ | |
1057 | + public boolean accept( final FileOperationInfo exFileInfo ) { | |
1058 | + return (exFileInfo.isHidden() ^ !flg) ^ rvse; | |
1059 | + } | |
848 | 1060 | } |
849 | 1061 | |
850 | 1062 | /** |
@@ -861,7 +1073,7 @@ | ||
861 | 1073 | buf.append( "no[" ).append( i ).append( "]=" ); |
862 | 1074 | buf.append( list.get(i) ).append( "\n" ); |
863 | 1075 | } |
864 | - | |
1076 | + | |
865 | 1077 | return buf.toString(); |
866 | 1078 | } |
867 | 1079 | } |
@@ -884,7 +1096,9 @@ | ||
884 | 1096 | * @author Kazuhiko Hasegawa |
885 | 1097 | * @since JDK5.0, |
886 | 1098 | */ |
887 | -class ModifyFileFilter implements FileFilter { | |
1099 | +// 5.10.8.0 (2019/02/01) MOD implementsにFileOperationFileFilterを追加 | |
1100 | +//class ModifyFileFilter implements FileFilter { | |
1101 | +class ModifyFileFilter implements FileFilter, FileOperationFileFilter { | |
888 | 1102 | private final long modify ; |
889 | 1103 | |
890 | 1104 | /** |
@@ -966,4 +1180,16 @@ | ||
966 | 1180 | public boolean accept( final File file ) { |
967 | 1181 | return file.isDirectory() || ( file.lastModified() >= modify ) ; |
968 | 1182 | } |
1183 | + | |
1184 | + /** | |
1185 | + * FileOperationFileFilter インターフェースの accept( FileOperationInfo ) メソッド | |
1186 | + * | |
1187 | + * @param exFileInfo 拡張ファイルオブジェクト | |
1188 | + * | |
1189 | + * @return true:処理対象 / false:処理非対象 | |
1190 | + * @see org.opengion.fukurou.model.FileOperationFileFilter#accept(FileOperationInfo) | |
1191 | + */ | |
1192 | + public boolean accept( final FileOperationInfo exFileInfo) { | |
1193 | + return exFileInfo.isDirectory() || ( exFileInfo.lastModified() >= modify ); | |
1194 | + } | |
969 | 1195 | } |
@@ -0,0 +1,39 @@ | ||
1 | +package org.opengion.hayabusa.io; | |
2 | + | |
3 | +import org.opengion.fukurou.model.FileOperationFactory; | |
4 | +import org.opengion.fukurou.model.FileOperation; | |
5 | +import org.opengion.fukurou.util.StringUtil; | |
6 | +import org.opengion.hayabusa.common.HybsSystem; | |
7 | + | |
8 | +/** | |
9 | + * クラウド別のクラス生成 | |
10 | + * | |
11 | + * @og.rev 5.10.8.0 (2019/02/01) 新規作成 | |
12 | + * @og.group | |
13 | + * | |
14 | + * @version 5.0 | |
15 | + * @author Takahashi Masakazu | |
16 | + * @sinse JDK7.0 | |
17 | + */ | |
18 | +public class HybsFileOperationFactory { | |
19 | + private static String defPlugin=HybsSystem.sys("CLOUD_TARGET"); | |
20 | + | |
21 | + /** | |
22 | + * コンストラクタはprivate化しておきます。 | |
23 | + */ | |
24 | + private HybsFileOperationFactory(){ | |
25 | + // コンストラクタ | |
26 | + } | |
27 | + | |
28 | + /** | |
29 | + * fukurouのFileOperationFactoryを呼び出してFOInterfaceを取得します。 | |
30 | + * pluginを指定しない場合はシステムリソースを利用します。 | |
31 | + * | |
32 | + * @param plugin | |
33 | + * @param path | |
34 | + * @return FileOperationInterface | |
35 | + */ | |
36 | + public static FileOperation create(String plugin, String path) { | |
37 | + return FileOperationFactory.newStorageOperation(StringUtil.nval(plugin, defPlugin), path); | |
38 | + } | |
39 | +} |
@@ -0,0 +1,454 @@ | ||
1 | +package org.opengion.plugin.cloud; | |
2 | + | |
3 | +import java.io.ByteArrayInputStream; | |
4 | +import java.io.FileNotFoundException; | |
5 | +import java.io.IOException; | |
6 | +import java.io.InputStream; | |
7 | +import java.util.ArrayList; | |
8 | +import java.util.List; | |
9 | + | |
10 | +import org.apache.commons.lang3.StringUtils; | |
11 | +import org.opengion.fukurou.model.AbstractFileOperation; | |
12 | +import org.opengion.fukurou.model.FileOperation; | |
13 | +import org.opengion.fukurou.model.FileOperationFileFilter; | |
14 | +import org.opengion.fukurou.model.FileOperationInfo; | |
15 | +import org.opengion.fukurou.util.Closer; | |
16 | +import org.opengion.fukurou.util.StringUtil; | |
17 | +import org.opengion.hayabusa.common.HybsSystem; | |
18 | +import org.opengion.hayabusa.common.HybsSystemException; | |
19 | + | |
20 | +import com.amazonaws.auth.AWSCredentials; | |
21 | +import com.amazonaws.auth.AWSStaticCredentialsProvider; | |
22 | +import com.amazonaws.auth.BasicAWSCredentials; | |
23 | +import com.amazonaws.auth.InstanceProfileCredentialsProvider; | |
24 | +import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration; | |
25 | +import com.amazonaws.services.s3.AmazonS3; | |
26 | +import com.amazonaws.services.s3.AmazonS3ClientBuilder; | |
27 | +import com.amazonaws.services.s3.model.AmazonS3Exception; | |
28 | +import com.amazonaws.services.s3.model.ListObjectsV2Request; | |
29 | +import com.amazonaws.services.s3.model.ListObjectsV2Result; | |
30 | +import com.amazonaws.services.s3.model.ObjectListing; | |
31 | +import com.amazonaws.services.s3.model.ObjectMetadata; | |
32 | +import com.amazonaws.services.s3.model.PutObjectRequest; | |
33 | +import com.amazonaws.services.s3.model.S3Object; | |
34 | +import com.amazonaws.services.s3.model.S3ObjectSummary; | |
35 | + | |
36 | +/** | |
37 | + * FileOperation_AWSは、S3ストレージに対して、 | |
38 | + * ファイル操作を行うクラスです。 | |
39 | + * | |
40 | + * 認証は下記の2通りが可能です。 | |
41 | + * ・実行サーバのEC2のインスタンスに、S3ストレージのアクセス許可を付与する | |
42 | + * ・システムリソースにアクセスキー・シークレットキー・エンドポイント・レギオンを登録する | |
43 | + * (CLOUD_STORAGE_S3_ACCESS_KEY、CLOUD_STORAGE_S3_SECRET_KEY、CLOUD_STORAGE_S3_SERVICE_END_POINT、CLOUD_STORAGE_S3_REGION) | |
44 | + * | |
45 | + * 注意: | |
46 | + * バケット名は全ユーザで共有のため、自身のバケット名か、作成されていないバケット名を指定する必要があります。 | |
47 | + * | |
48 | + * @og.rev 5.10.8.0 (2019/02/01) 新規作成 | |
49 | + * | |
50 | + * @version 5 | |
51 | + * @author oota | |
52 | + * @sinse JDK7.0 | |
53 | + */ | |
54 | +public class FileOperation_AWS extends AbstractFileOperation { | |
55 | + /** クラス変数 */ | |
56 | + private final AmazonS3 amazonS3; | |
57 | + private final String conBuket; | |
58 | + | |
59 | + /** | |
60 | + * コンストラクター | |
61 | + * @param buket バケット | |
62 | + * @param inPath パス | |
63 | + */ | |
64 | + public FileOperation_AWS(String buket, String inPath) { | |
65 | + super( StringUtil.nval( buket, HybsSystem.sys("CLOUD_BUCKET") ), inPath); | |
66 | + conBuket = buket; | |
67 | + | |
68 | + // アクセスキー | |
69 | + final String s3AccessKey = HybsSystem.sys("CLOUD_STORAGE_S3_ACCESS_KEY"); | |
70 | + String s3SecretKey = ""; | |
71 | + String s3ServiceEndPoint = ""; | |
72 | + String s3Region = ""; | |
73 | + | |
74 | + // S3アクセスクライアントの生成 | |
75 | + if (StringUtils.isEmpty(s3AccessKey)) { | |
76 | + // IAMロールによる認証 | |
77 | + amazonS3 = AmazonS3ClientBuilder.standard() | |
78 | + .withCredentials(new InstanceProfileCredentialsProvider(false)) | |
79 | + .build(); | |
80 | + } else { | |
81 | + // リソースのアクセスキーによる認証 | |
82 | + // シークレットキー | |
83 | + s3SecretKey = HybsSystem.sys("CLOUD_STORAGE_S3_SECRET_KEY"); | |
84 | + // エンドポイント | |
85 | + s3ServiceEndPoint = HybsSystem.sys("CLOUD_STORAGE_S3_SERVICE_END_POINT"); | |
86 | + // レギオン | |
87 | + s3Region = HybsSystem.sys("CLOUD_STORAGE_S3_REGION"); | |
88 | + | |
89 | + // AWSの認証情報 | |
90 | + AWSCredentials credentials = new BasicAWSCredentials(s3AccessKey, s3SecretKey); | |
91 | + | |
92 | + // エンドポイント設定 | |
93 | + EndpointConfiguration endpointConfiguration = new EndpointConfiguration(s3ServiceEndPoint, s3Region); | |
94 | + amazonS3 = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials)) | |
95 | + .withEndpointConfiguration(endpointConfiguration) | |
96 | + .build(); | |
97 | + } | |
98 | + | |
99 | + try { | |
100 | + // S3に指定されたバケット(コンテナ)が存在しない場合は、作成する | |
101 | + if (!amazonS3.doesBucketExist(bucket)) { // doesBucketExistV2最新JARだと出ている | |
102 | + amazonS3.createBucket(bucket); | |
103 | + } | |
104 | + } catch (AmazonS3Exception ase) { | |
105 | + StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
106 | + if (StringUtils.isEmpty(s3AccessKey)) { | |
107 | + errMsg.append("IAMロールによる認証が失敗しました。"); | |
108 | + | |
109 | + } else { | |
110 | + errMsg.append("アクセスキーによる認証が失敗しました。"); | |
111 | + errMsg.append(" CLOUD_STORAGE_S3_ACCESS_KEY:").append(s3AccessKey); | |
112 | + errMsg.append(" CLOUD_STORAGE_S3_SECRET_KEY:非表示"); | |
113 | + errMsg.append(" CLOUD_STORAGE_S3_SERVICE_END_POINT:").append(s3ServiceEndPoint); | |
114 | + errMsg.append(" CLOUD_STORAGE_S3_REGION:").append(s3Region); | |
115 | + } | |
116 | + errMsg.append(" システムエラー情報:").append(ase.getMessage()); | |
117 | + throw new HybsSystemException(errMsg.toString()); | |
118 | + } | |
119 | + } | |
120 | + | |
121 | + /** | |
122 | + * InputStreamのデータを書き込みます。 | |
123 | + * | |
124 | + * @param is 書き込みデータのInputStream | |
125 | + * @throws IOException | |
126 | + */ | |
127 | + @Override | |
128 | + public void write(InputStream is) throws IOException { | |
129 | + ByteArrayInputStream bais = null; | |
130 | + try { | |
131 | + ObjectMetadata om = new ObjectMetadata(); | |
132 | + | |
133 | + byte[] bytes = toByteArray(is); | |
134 | + om.setContentLength(bytes.length); | |
135 | + bais = new ByteArrayInputStream(bytes); | |
136 | + | |
137 | + PutObjectRequest request = new PutObjectRequest(bucket, path, bais, om); | |
138 | + | |
139 | + amazonS3.putObject(request); | |
140 | + } catch (Exception e) { | |
141 | + StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
142 | + errMsg.append("AWSバケットに書き込みが失敗しました。path:").append(path); | |
143 | + errMsg.append(" システムエラー情報:").append(e.getMessage()); | |
144 | + throw new IOException(errMsg.toString()); | |
145 | + } finally { | |
146 | + Closer.ioClose(bais); | |
147 | + } | |
148 | + } | |
149 | + | |
150 | + /** | |
151 | + * データを読み込み、InputStreamとして、返します。 | |
152 | + * | |
153 | + * @return 読み込みデータのInputStream | |
154 | + * @throws FileNotFoundException | |
155 | + */ | |
156 | + @Override | |
157 | + public InputStream read() throws FileNotFoundException { | |
158 | + S3Object object = null; | |
159 | + | |
160 | + try { | |
161 | + object = amazonS3.getObject(bucket, path); | |
162 | + } catch (Exception e) { | |
163 | + StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
164 | + errMsg.append("AWSバケットから読み込みが失敗しました。path:").append(path); | |
165 | + errMsg.append(" システムエラー情報:").append(e.getMessage()); | |
166 | + throw new FileNotFoundException(errMsg.toString()); | |
167 | + } | |
168 | + return object.getObjectContent(); | |
169 | + } | |
170 | + | |
171 | + /** | |
172 | + * ファイルを削除します。 | |
173 | + * | |
174 | + * @return 成否フラグ | |
175 | + */ | |
176 | + @Override | |
177 | + public boolean delete() { | |
178 | + boolean flgRtn = false; | |
179 | + | |
180 | + try { | |
181 | + if (isFile()) { | |
182 | + // ファイル削除 | |
183 | + amazonS3.deleteObject(bucket, path); | |
184 | + } else if (isDirectory()) { | |
185 | + // ディレクトリ削除 | |
186 | + // 一括削除のapiが無いので、繰り返しで削除を行う | |
187 | + ObjectListing objectList = amazonS3.listObjects(bucket, path); | |
188 | + List<S3ObjectSummary> list = objectList.getObjectSummaries(); | |
189 | + for (S3ObjectSummary obj : list) { | |
190 | + amazonS3.deleteObject(bucket, obj.getKey()); | |
191 | + } | |
192 | + | |
193 | + } | |
194 | + flgRtn = true; | |
195 | + } catch (Exception e) { | |
196 | + // エラーはスルーして、falseを返す | |
197 | + } | |
198 | + | |
199 | + return flgRtn; | |
200 | + } | |
201 | + | |
202 | + /** | |
203 | + * ファイルを指定先に、コピーします。 | |
204 | + * | |
205 | + * @param afPath コピー先 | |
206 | + * @return 成否フラグ | |
207 | + */ | |
208 | + @Override | |
209 | + public boolean copy(String afPath) { | |
210 | + boolean flgRtn = false; | |
211 | + | |
212 | + try { | |
213 | + amazonS3.copyObject(bucket, path, bucket, afPath); | |
214 | + flgRtn = true; | |
215 | + } catch (Exception e) { | |
216 | + // エラーはスルーして、falseを返す | |
217 | + } | |
218 | + | |
219 | + return flgRtn; | |
220 | + } | |
221 | + | |
222 | + /** | |
223 | + * ファイルサイズを返します | |
224 | + * | |
225 | + * @return ファイルサイズ | |
226 | + */ | |
227 | + @Override | |
228 | + public long length() { | |
229 | + long rtn = 0; | |
230 | + | |
231 | + try { | |
232 | + ObjectMetadata meta = amazonS3.getObjectMetadata(bucket, path); | |
233 | + rtn = meta.getContentLength(); | |
234 | + } catch (Exception e) { | |
235 | + // エラーはスルーして、0を返す。 | |
236 | + } | |
237 | + return rtn; | |
238 | + } | |
239 | + | |
240 | + /** | |
241 | + * 最終更新時刻を取得します。 | |
242 | + * | |
243 | + * @return 最終更新時刻 | |
244 | + */ | |
245 | + @Override | |
246 | + public long lastModified() { | |
247 | + long rtn = 0; | |
248 | + | |
249 | + try { | |
250 | + ObjectMetadata meta = amazonS3.getObjectMetadata(bucket, path); | |
251 | + rtn = meta.getLastModified().getTime(); | |
252 | + } catch (Exception e) { | |
253 | + // エラーはスルーして、0を返す | |
254 | + } | |
255 | + return rtn; | |
256 | + } | |
257 | + | |
258 | + /** | |
259 | + * ファイルの場合は、trueを返します。 | |
260 | + * | |
261 | + * @return ファイルフラグ | |
262 | + */ | |
263 | + @Override | |
264 | + public boolean isFile() { | |
265 | + return amazonS3.doesObjectExist(bucket, path); | |
266 | + } | |
267 | + | |
268 | + /** | |
269 | + * ディレクトリの場合は、trueを返します。 | |
270 | + * | |
271 | + * @return ディレクトリフラグ | |
272 | + */ | |
273 | + @Override | |
274 | + public boolean isDirectory() { | |
275 | + boolean flgRtn = false; | |
276 | + | |
277 | + if (StringUtils.isEmpty(path)) { | |
278 | + return true; | |
279 | + } | |
280 | + | |
281 | + // S3にはディレクトリの概念はないので、「/」で続くデータが存在するかで、判定 | |
282 | + ObjectListing objectList = amazonS3.listObjects(bucket, setDirTail(path)); | |
283 | + List<S3ObjectSummary> list = objectList.getObjectSummaries(); | |
284 | + flgRtn = list.size() == 0 ? false : true; | |
285 | + | |
286 | + return flgRtn; | |
287 | + } | |
288 | + | |
289 | + /** | |
290 | + * パスのファイルとディレクトリ一覧を取得します。 | |
291 | + * | |
292 | + * @return ファイルとティレクトリ一覧 | |
293 | + */ | |
294 | + @Override | |
295 | + public FileOperation[] listFiles(FileOperationFileFilter filter) { | |
296 | + if (!exists()) { | |
297 | + return new FileOperationInfo[0]; | |
298 | + } | |
299 | + | |
300 | + String search = path; | |
301 | + if (isDirectory()) { | |
302 | + search = setDirTail(path); | |
303 | + } | |
304 | + | |
305 | + List<FileOperationInfo> rtnList = new ArrayList<FileOperationInfo>(); | |
306 | + | |
307 | + // 検索処理 | |
308 | + ListObjectsV2Request request = new ListObjectsV2Request() | |
309 | + .withBucketName(bucket) | |
310 | + .withPrefix(search) | |
311 | + .withDelimiter("/"); | |
312 | + ListObjectsV2Result list = amazonS3.listObjectsV2(request); | |
313 | + List<S3ObjectSummary> objects = list.getObjectSummaries(); | |
314 | + | |
315 | + // ファイル情報の取得 | |
316 | + for (S3ObjectSummary obj : objects) { | |
317 | + String key = obj.getKey(); | |
318 | + | |
319 | + FileOperationInfo file = new FileOperationInfo(); | |
320 | + file.setPath(key); | |
321 | + file.setName(drawName(key)); | |
322 | + file.setParent(drawParent(key)); | |
323 | + file.setLastModifiedValue(obj.getLastModified().getTime()); | |
324 | + file.setFile(true); | |
325 | + file.setSize(obj.getSize()); | |
326 | + rtnList.add(file); | |
327 | + } | |
328 | + | |
329 | + // ディレクトリ情報の取得 | |
330 | + List<String> folders = list.getCommonPrefixes(); | |
331 | + for (String str : folders) { | |
332 | + String key = rTrim(str, '/'); | |
333 | + | |
334 | + FileOperationInfo file = new FileOperationInfo(); | |
335 | + file.setPath(key); | |
336 | + file.setName(drawName(key)); | |
337 | + file.setParent(drawParent(key)); | |
338 | + file.setDirectory(true); | |
339 | + rtnList.add(file); | |
340 | + } | |
341 | + | |
342 | + // フィルタ処理 | |
343 | + FileOperation[] filterList = filter(rtnList, filter); | |
344 | + | |
345 | + return filterList; | |
346 | + } | |
347 | + | |
348 | + /** | |
349 | + * 親のディレクトリを返します。 | |
350 | + * | |
351 | + * @return 親のディレクトリ | |
352 | + */ | |
353 | + @Override | |
354 | + public FileOperation getParentFile() { | |
355 | + return new FileOperation_AWS(conBuket,getParent()); | |
356 | + } | |
357 | + | |
358 | + /** 以下はローカル環境でのテスト用メソッドです。 */ | |
359 | +// /** | |
360 | +// * ローカルでのテスト用コンストラクタ | |
361 | +// * | |
362 | +// * 要:super.bucketの値は固定値に変更してください。 | |
363 | +// * | |
364 | +// * @param inPath | |
365 | +// */ | |
366 | +// public FileOperation_AWS(String buket, String inPath, boolean test) { | |
367 | +// // super( StringUtil.nval( buket, HybsSystem.sys("CLOUD_BUCKET") ), inPath); | |
368 | +// super( StringUtil.nval( buket, "opengiontestbucket" ), inPath); | |
369 | +// conBuket = buket; | |
370 | +// | |
371 | +// // aws接続情報 | |
372 | +// String s3AccessKey = "[キー]"; | |
373 | +// String s3SecretKey = "[シークレットキー]"; | |
374 | +// String s3ServiceEndPoint = "s3-ap-northeast-1.amazonaws.com"; | |
375 | +// String s3Region = "ap-northeast-1"; | |
376 | +// | |
377 | +// // proxy環境での設定 | |
378 | +// ClientConfiguration conf = new ClientConfiguration(); | |
379 | +// conf.setProtocol(Protocol.HTTPS); | |
380 | +// conf.setProxyHost("mtc-px14"); | |
381 | +// conf.setProxyPort(8081); | |
382 | +// | |
383 | +// // AWSの認証情報 | |
384 | +// AWSCredentials credentials = new BasicAWSCredentials(s3AccessKey, s3SecretKey); | |
385 | +// | |
386 | +// // エンドポイント設定 | |
387 | +// EndpointConfiguration endpointConfiguration = new EndpointConfiguration(s3ServiceEndPoint, s3Region); | |
388 | +// amazonS3 = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials)) | |
389 | +// .withEndpointConfiguration(endpointConfiguration) | |
390 | +// .withClientConfiguration(conf) // テスト用にproxy設定 | |
391 | +// .build(); | |
392 | +// | |
393 | +// try { | |
394 | +// // S3に指定されたバケット(コンテナ)が存在しない場合は、作成する | |
395 | +// if (!amazonS3.doesBucketExistV2(bucket)) { | |
396 | +// amazonS3.createBucket(bucket); | |
397 | +// } | |
398 | +// } catch (AmazonS3Exception ase) { | |
399 | +// StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
400 | +// if (StringUtils.isEmpty(s3AccessKey)) { | |
401 | +// errMsg.append("IAMロールによる認証か、バケットの作成が失敗しました。"); | |
402 | +// | |
403 | +// } else { | |
404 | +// errMsg.append("アクセスキーによる認証かバケットの作成が失敗しました。"); | |
405 | +// errMsg.append(" CLOUD_STORAGE_S3_ACCESS_KEY:").append(s3AccessKey); | |
406 | +// errMsg.append(" CLOUD_STORAGE_S3_SECRET_KEY:非表示"); | |
407 | +// errMsg.append(" CLOUD_STORAGE_S3_SERVICE_END_POINT:").append(s3ServiceEndPoint); | |
408 | +// errMsg.append(" CLOUD_STORAGE_S3_REGION:").append(s3Region); | |
409 | +// } | |
410 | +// errMsg.append(" バケット名:").append(bucket); | |
411 | +// errMsg.append(" システムエラー情報:").append(ase.getMessage()); | |
412 | +// throw new RuntimeException(errMsg.toString()); | |
413 | +// } | |
414 | +// } | |
415 | +// | |
416 | +// /** テスト用メソッド */ | |
417 | +// public static void main(String[] args) { | |
418 | +// writeTest(); | |
419 | +//// listTest(); | |
420 | +//// methodTest(); | |
421 | +// } | |
422 | +// | |
423 | +// public static void writeTest() { | |
424 | +// FileOperation file = new FileOperation_AWS("", "sample/test.txt", true); | |
425 | +// | |
426 | +// try(InputStream is = new ByteArrayInputStream("sample".getBytes())){ | |
427 | +// file.write(is); | |
428 | +// }catch(Exception e) { | |
429 | +// System.out.println(e.getMessage()); | |
430 | +// } | |
431 | +// } | |
432 | +// | |
433 | +// public static void listTest() { | |
434 | +// FileOperation file = new FileOperation_AWS("", "sample", true); | |
435 | +// | |
436 | +// // フィルタ設定 | |
437 | +// HybsFileFilter filter = new HybsFileFilter(); | |
438 | +// filter.startsWith("te"); | |
439 | +// | |
440 | +// FileOperation[] list = file.listFiles(filter); | |
441 | +// System.out.println(list.length); | |
442 | +// for(FileOperation f: list) { | |
443 | +// System.out.println(f.getPath()); | |
444 | +// } | |
445 | +// } | |
446 | +// | |
447 | +// public static void methodTest() { | |
448 | +// FileOperation file = new FileOperation_AWS("", "test", true); | |
449 | +// boolean rtn = false; | |
450 | +// rtn = file.isFile(); | |
451 | +// | |
452 | +// System.out.println(rtn); | |
453 | +// } | |
454 | +} |
@@ -0,0 +1,366 @@ | ||
1 | +package org.opengion.plugin.cloud; | |
2 | + | |
3 | +import java.io.ByteArrayInputStream; | |
4 | +import java.io.FileNotFoundException; | |
5 | +import java.io.IOException; | |
6 | +import java.io.InputStream; | |
7 | +import java.util.ArrayList; | |
8 | +import java.util.List; | |
9 | + | |
10 | +import org.opengion.fukurou.model.AbstractFileOperation; | |
11 | +import org.opengion.fukurou.model.FileOperationFileFilter; | |
12 | +import org.opengion.fukurou.model.FileOperationInfo; | |
13 | +import org.opengion.fukurou.model.FileOperation; | |
14 | +import org.opengion.fukurou.util.StringUtil; | |
15 | +import org.opengion.hayabusa.common.HybsSystem; | |
16 | +import org.opengion.hayabusa.common.HybsSystemException; | |
17 | + | |
18 | +import com.microsoft.azure.storage.CloudStorageAccount; | |
19 | +import com.microsoft.azure.storage.blob.CloudBlob; | |
20 | +import com.microsoft.azure.storage.blob.CloudBlobClient; | |
21 | +import com.microsoft.azure.storage.blob.CloudBlobContainer; | |
22 | +import com.microsoft.azure.storage.blob.CloudBlobDirectory; | |
23 | +import com.microsoft.azure.storage.blob.CloudBlockBlob; | |
24 | +import com.microsoft.azure.storage.blob.ListBlobItem; | |
25 | + | |
26 | +/** | |
27 | + * FileOperation_AZURE.javaは、Azureのストレージに対して、 | |
28 | + * ファイル操作を行うクラスです。 | |
29 | + * | |
30 | + * @og.rev 5.10.8.0 (2019/02/01) 新規作成 | |
31 | + * | |
32 | + * @version 5 | |
33 | + * @author oota | |
34 | + * @since JDK7.0 | |
35 | + */ | |
36 | +public class FileOperation_AZURE extends AbstractFileOperation { | |
37 | + /** クラス変数 */ | |
38 | + private final CloudBlobContainer azureContainer; | |
39 | + private final String conBuket; | |
40 | + | |
41 | + /** | |
42 | + * コンストラクター | |
43 | + * @param buket バケット | |
44 | + * @param inPath パス | |
45 | + */ | |
46 | + public FileOperation_AZURE(String buket, String inPath) { | |
47 | + super( StringUtil.nval( buket, HybsSystem.sys("CLOUD_BUCKET") ), inPath); | |
48 | + conBuket = buket; | |
49 | + | |
50 | + String storageConnectionString = HybsSystem.sys("CLOUD_STORAGE_AZURE_KEY"); | |
51 | + | |
52 | + if (StringUtil.isNull(storageConnectionString)) { | |
53 | + String errMsg = "Azure用認証キー(CLOUD_STORAGE_AZURE_KEY)がシステムリソースに登録されていません。"; | |
54 | + throw new HybsSystemException(errMsg); | |
55 | + } | |
56 | + | |
57 | + try { | |
58 | + CloudStorageAccount account = CloudStorageAccount.parse(storageConnectionString); | |
59 | + CloudBlobClient serviceClient = account.createCloudBlobClient(); | |
60 | + azureContainer = serviceClient.getContainerReference(bucket); | |
61 | + // コンテナが存在しない場合は作成する | |
62 | + azureContainer.createIfNotExists(); | |
63 | + } catch (Exception e) { | |
64 | + StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
65 | + errMsg.append("コンテナの作成に失敗しました。container:").append(bucket); | |
66 | + errMsg.append(" システムエラー情報:").append(e.getMessage()); | |
67 | + throw new HybsSystemException(errMsg.toString()); | |
68 | + } | |
69 | + } | |
70 | + | |
71 | + /** | |
72 | + * InputStreamのデータを書き込みます。 | |
73 | + * | |
74 | + * @param is 書き込みデータのInputStream | |
75 | + * @throws IOException | |
76 | + */ | |
77 | + @Override | |
78 | + public void write(InputStream is) throws IOException { | |
79 | + try { | |
80 | + CloudBlockBlob blob = azureContainer.getBlockBlobReference(path); | |
81 | + byte[] bytes = toByteArray(is); | |
82 | + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); | |
83 | + | |
84 | + blob.upload(bais, bytes.length); | |
85 | + } catch (Exception e) { | |
86 | + StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
87 | + errMsg.append("Azureストレージに書き込みが失敗しました。path:").append(path); | |
88 | + errMsg.append(" システムエラー情報:").append(e.getMessage()); | |
89 | + throw new IOException(errMsg.toString()); | |
90 | + } | |
91 | + } | |
92 | + | |
93 | + /** | |
94 | + * データを読み込み、InputStreamとして、返します。 | |
95 | + * | |
96 | + * @return 読み込みデータのInputStream | |
97 | + * @throws FileNotFoundException | |
98 | + */ | |
99 | + @Override | |
100 | + public InputStream read() throws FileNotFoundException { | |
101 | + CloudBlockBlob blob; | |
102 | + InputStream is; | |
103 | + try { | |
104 | + blob = azureContainer.getBlockBlobReference(path); | |
105 | + is = blob.openInputStream(); | |
106 | + } catch (Exception e) { | |
107 | + StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
108 | + errMsg.append("Azureストレージから読み込みが失敗しました。path:").append(path); | |
109 | + errMsg.append(" システムエラー情報:").append(e.getMessage()); | |
110 | + throw new FileNotFoundException(errMsg.toString()); | |
111 | + } | |
112 | + return is; | |
113 | + } | |
114 | + | |
115 | + /** | |
116 | + * ファイルを削除します。 | |
117 | + * | |
118 | + * @return 成否フラグ | |
119 | + */ | |
120 | + @Override | |
121 | + public boolean delete() { | |
122 | + boolean flgRtn = false; | |
123 | + | |
124 | + try { | |
125 | + azureContainer.getBlockBlobReference(path).delete(); | |
126 | + flgRtn = true; | |
127 | + } catch (Exception e) { | |
128 | + // エラーはスルーして、falseを返す | |
129 | + } | |
130 | + | |
131 | + return flgRtn; | |
132 | + } | |
133 | + | |
134 | + /** | |
135 | + * ファイルを指定先に、コピーします。 | |
136 | + * | |
137 | + * @param afPath コピー先 | |
138 | + * @return 成否フラグ | |
139 | + */ | |
140 | + @Override | |
141 | + public boolean copy(String afPath) { | |
142 | + boolean flgRtn = false; | |
143 | + | |
144 | + try { | |
145 | + CloudBlockBlob copyTrg = azureContainer.getBlockBlobReference(path); | |
146 | + CloudBlockBlob copySaki = azureContainer.getBlockBlobReference(afPath); | |
147 | + | |
148 | + copySaki.startCopy(copyTrg); | |
149 | + flgRtn = true; | |
150 | + } catch (Exception e) { | |
151 | + // エラーはスルーして、falseを返す | |
152 | + } | |
153 | + | |
154 | + return flgRtn; | |
155 | + } | |
156 | + | |
157 | + /** | |
158 | + * ファイルサイズを返します | |
159 | + * | |
160 | + * @return ファイルサイズ | |
161 | + */ | |
162 | + @Override | |
163 | + public long length() { | |
164 | + long rtn = 0; | |
165 | + | |
166 | + try { | |
167 | + CloudBlob blob = azureContainer.getBlockBlobReference(path); | |
168 | + rtn = blob.getProperties().getLength(); | |
169 | + } catch (Exception e) { | |
170 | + // スルーして、0を返す | |
171 | + } | |
172 | + return rtn; | |
173 | + } | |
174 | + | |
175 | + /** | |
176 | + * 最終更新時刻を取得します。 | |
177 | + * | |
178 | + * @return 最終更新時刻 | |
179 | + */ | |
180 | + @Override | |
181 | + public long lastModified() { | |
182 | + long rtn = 0; | |
183 | + | |
184 | + try { | |
185 | + CloudBlob blob = azureContainer.getBlockBlobReference(path); | |
186 | + rtn = blob.getProperties().getLastModified().getTime(); | |
187 | + } catch (Exception e) { | |
188 | + // スルーして、0を返す | |
189 | + } | |
190 | + | |
191 | + return rtn; | |
192 | + } | |
193 | + | |
194 | + /** | |
195 | + * ファイルの場合は、trueを返します。 | |
196 | + * | |
197 | + * @return ファイルフラグ | |
198 | + */ | |
199 | + @Override | |
200 | + public boolean isFile() { | |
201 | + boolean blnRtn = false; | |
202 | + | |
203 | + try { | |
204 | + CloudBlockBlob blob = azureContainer.getBlockBlobReference(path); | |
205 | + | |
206 | + if (blob.exists()) { | |
207 | + blnRtn = true; | |
208 | + } | |
209 | + } catch (Exception e) { | |
210 | + // ここのエラーはスルーして、falseを返す | |
211 | + } | |
212 | + | |
213 | + return blnRtn; | |
214 | + } | |
215 | + | |
216 | + /** | |
217 | + * ディレクトリの場合は、trueを返します。 | |
218 | + * | |
219 | + * @return ディレクトリフラグ | |
220 | + */ | |
221 | + @Override | |
222 | + public boolean isDirectory() { | |
223 | + boolean blnRtn = false; | |
224 | + | |
225 | + // 後尾に「/」をつけないこと | |
226 | + for (ListBlobItem item : azureContainer.listBlobs(rTrim(path, '/'))) { | |
227 | + if (item instanceof CloudBlobDirectory) { | |
228 | + blnRtn = true; | |
229 | + break; | |
230 | + } | |
231 | + } | |
232 | + | |
233 | + return blnRtn; | |
234 | + } | |
235 | + | |
236 | + /** | |
237 | + * パスのファイルとディレクトリ一覧を取得します。 | |
238 | + * | |
239 | + * @return ファイルとティレクトリ一覧 | |
240 | + */ | |
241 | + @Override | |
242 | + public FileOperation[] listFiles(FileOperationFileFilter filter) { | |
243 | + if (!exists()) { | |
244 | + return new FileOperationInfo[0]; | |
245 | + } | |
246 | + | |
247 | + String search = path; | |
248 | + if (isDirectory()) { | |
249 | + search = setDirTail(path); | |
250 | + } | |
251 | + | |
252 | + List<FileOperationInfo> rtnList = new ArrayList<FileOperationInfo>(); | |
253 | + | |
254 | + for (ListBlobItem item : azureContainer.listBlobs(search)) { | |
255 | + if (item instanceof CloudBlob) { | |
256 | + // ファイルの情報を設定 | |
257 | + CloudBlob blob = (CloudBlob) item; | |
258 | + FileOperationInfo fi = new FileOperationInfo(); | |
259 | + fi.setPath(blob.getName()); | |
260 | + fi.setName(drawName(blob.getName())); | |
261 | + fi.setParent(drawParent(blob.getName())); | |
262 | + fi.setLastModifiedValue(blob.getProperties().getLastModified().getTime()); | |
263 | + fi.setSize(blob.getProperties().getLength()); | |
264 | + fi.setFile(true); | |
265 | + rtnList.add(fi); | |
266 | + } else if (item instanceof CloudBlobDirectory) { | |
267 | + // ディレクトリの情報を設定 | |
268 | + CloudBlobDirectory directory = (CloudBlobDirectory) item; | |
269 | + FileOperationInfo fi = new FileOperationInfo(); | |
270 | + final String key = rTrim(directory.getPrefix(), '/'); | |
271 | + fi.setPath(key); | |
272 | + fi.setName(drawName(key)); | |
273 | + fi.setParent(drawParent(key)); | |
274 | + fi.setDirectory(true); | |
275 | + rtnList.add(fi); | |
276 | + } | |
277 | + } | |
278 | + | |
279 | + FileOperation[] filterList = filter(rtnList, filter); | |
280 | + | |
281 | + return filterList; | |
282 | + } | |
283 | + | |
284 | + /** | |
285 | + * 親のディレクトリを返します。 | |
286 | + * | |
287 | + * @return 親のディレクトリ | |
288 | + */ | |
289 | + @Override | |
290 | + public FileOperation getParentFile() { | |
291 | + return new FileOperation_AZURE(conBuket,getParent()); | |
292 | + } | |
293 | + | |
294 | + /** 以下はローカル環境でのテスト用メソッドです。 */ | |
295 | +// /** | |
296 | +// * ローカルでのテスト用コンストラクタ | |
297 | +// * | |
298 | +// * 要:super.bucketの値は固定値に変更してください。 | |
299 | +// * | |
300 | +// * @param inPath | |
301 | +// */ | |
302 | +// public FileOperation_AZURE(String buket, String inPath, boolean test) { | |
303 | +// // super( StringUtil.nval( buket, HybsSystem.sys("CLOUD_BUCKET") ), inPath); | |
304 | +// super( StringUtil.nval( buket, "opengiontestbucket" ), inPath); | |
305 | +// conBuket = buket; | |
306 | +// | |
307 | +// // ローカル環境で実行する場合の、proxy設定 | |
308 | +// System.setProperty("https.proxyHost","mtc-px14"); | |
309 | +// System.setProperty("https.proxyPort","8081"); | |
310 | +// | |
311 | +// String storageConnectionString = "[接続文字列]"; | |
312 | +// | |
313 | +// if (StringUtil.isNull(storageConnectionString)) { | |
314 | +// String errMsg = "Azure用認証キー(CLOUD_STORAGE_AZURE_KEY)がシステムリソースに登録されていません。"; | |
315 | +// throw new HybsSystemException(errMsg); | |
316 | +// } | |
317 | +// | |
318 | +// try { | |
319 | +// CloudStorageAccount account = CloudStorageAccount.parse(storageConnectionString); | |
320 | +// CloudBlobClient serviceClient = account.createCloudBlobClient(); | |
321 | +// azureContainer = serviceClient.getContainerReference(bucket); | |
322 | +// // コンテナが存在しない場合は作成する | |
323 | +// azureContainer.createIfNotExists(); | |
324 | +// } catch (Exception e) { | |
325 | +// StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
326 | +// errMsg.append("コンテナの作成に失敗しました。container:").append(bucket); | |
327 | +// errMsg.append(" システムエラー情報:").append(e.getMessage()); | |
328 | +// throw new HybsSystemException(errMsg.toString()); | |
329 | +// } | |
330 | +// } | |
331 | +// | |
332 | +// /** テスト用メソッド */ | |
333 | +// public static void main(String[] args) { | |
334 | +// // writeTest(); | |
335 | +// // listTest(); | |
336 | +// // methodTest(); | |
337 | +// } | |
338 | +// | |
339 | +// public static void writeTest() { | |
340 | +// FileOperation file = new FileOperation_AZURE("", "sample/test.txt", true); | |
341 | +// | |
342 | +// try (InputStream is = new ByteArrayInputStream("sample".getBytes())) { | |
343 | +// file.write(is); | |
344 | +// } catch (Exception e) { | |
345 | +// System.out.println(e.getMessage()); | |
346 | +// } | |
347 | +// } | |
348 | +// | |
349 | +// public static void listTest() { | |
350 | +// FileOperation file = new FileOperation_AZURE("", "sample", true); | |
351 | +// | |
352 | +// FileOperation[] list = file.listFiles(); | |
353 | +// System.out.println(list.length); | |
354 | +// for (FileOperation f : list) { | |
355 | +// System.out.println(f.getPath()); | |
356 | +// } | |
357 | +// } | |
358 | +// | |
359 | +// public static void methodTest() { | |
360 | +// FileOperation file = new FileOperation_AZURE("", "test", true); | |
361 | +// boolean rtn = false; | |
362 | +// rtn = file.isFile(); | |
363 | +// | |
364 | +// System.out.println(rtn); | |
365 | +// } | |
366 | +} |
@@ -0,0 +1,338 @@ | ||
1 | +package org.opengion.plugin.cloud; | |
2 | + | |
3 | +import java.io.ByteArrayInputStream; | |
4 | +import java.io.FileNotFoundException; | |
5 | +import java.io.IOException; | |
6 | +import java.io.InputStream; | |
7 | +import java.util.ArrayList; | |
8 | +import java.util.List; | |
9 | + | |
10 | +import org.apache.commons.lang3.StringUtils; | |
11 | +import org.opengion.fukurou.model.AbstractFileOperation; | |
12 | +import org.opengion.fukurou.model.FileOperationFileFilter; | |
13 | +import org.opengion.fukurou.model.FileOperationInfo; | |
14 | +import org.opengion.fukurou.model.FileOperation; | |
15 | +import org.opengion.fukurou.util.Closer; | |
16 | +import org.opengion.fukurou.util.StringUtil; | |
17 | +import org.opengion.hayabusa.common.HybsSystem; | |
18 | +import org.opengion.hayabusa.common.HybsSystemException; | |
19 | + | |
20 | +import com.ibm.cloud.objectstorage.SDKGlobalConfiguration; | |
21 | +import com.ibm.cloud.objectstorage.auth.AWSCredentials; | |
22 | +import com.ibm.cloud.objectstorage.auth.AWSStaticCredentialsProvider; | |
23 | +import com.ibm.cloud.objectstorage.client.builder.AwsClientBuilder.EndpointConfiguration; | |
24 | +import com.ibm.cloud.objectstorage.oauth.BasicIBMOAuthCredentials; | |
25 | +import com.ibm.cloud.objectstorage.services.s3.AmazonS3; | |
26 | +import com.ibm.cloud.objectstorage.services.s3.AmazonS3ClientBuilder; | |
27 | +import com.ibm.cloud.objectstorage.services.s3.model.AmazonS3Exception; | |
28 | +import com.ibm.cloud.objectstorage.services.s3.model.ListObjectsV2Request; | |
29 | +import com.ibm.cloud.objectstorage.services.s3.model.ListObjectsV2Result; | |
30 | +import com.ibm.cloud.objectstorage.services.s3.model.ObjectListing; | |
31 | +import com.ibm.cloud.objectstorage.services.s3.model.ObjectMetadata; | |
32 | +import com.ibm.cloud.objectstorage.services.s3.model.PutObjectRequest; | |
33 | +import com.ibm.cloud.objectstorage.services.s3.model.S3Object; | |
34 | +import com.ibm.cloud.objectstorage.services.s3.model.S3ObjectSummary; | |
35 | + | |
36 | +/** | |
37 | + * FileOperation_IBM.javaは、Bluemixのストレージ(S3と互換性があります)の、 | |
38 | + * ファイル操作を行うクラスです。 | |
39 | + * | |
40 | + * IBMCloud(Bluemix)のダッシュボードから、下記の値を取得して、 | |
41 | + * システムリソースに登録を行う必要があります。 | |
42 | + * | |
43 | + * CLOUD_STORAGE_S3_APIKEY、CLOUD_STORAGE_S3_SERVICEINSTANCEID、CLOUD_STORAGE_S3_SERVICE_END_POINT、CLOUD_STORAGE_S3_REGION | |
44 | + * | |
45 | + * @og.rev 5.10.8.0 (2019/02/01) 新規作成 | |
46 | + * | |
47 | + * @version 5 | |
48 | + * @author oota | |
49 | + * @since JDK7.0 | |
50 | + * | |
51 | + */ | |
52 | +public class FileOperation_IBM extends AbstractFileOperation { | |
53 | + /** クラス変数 */ | |
54 | + private final AmazonS3 amazonS3; | |
55 | + private final String conBuket; | |
56 | + private static final String COS_AUTH_ENDPOINT = "https://iam.ng.bluemix.net/oidc/token"; | |
57 | + | |
58 | + /** | |
59 | + * コンストラクター | |
60 | + * @param buket バケット | |
61 | + * @param inPath パス | |
62 | + */ | |
63 | + public FileOperation_IBM(String buket, String inPath) { | |
64 | + super(StringUtil.nval( buket, HybsSystem.sys("CLOUD_BUCKET") ),inPath); | |
65 | + conBuket = buket; | |
66 | + | |
67 | + // 公式のマニュアルにより、下記のENDPOINTを設定 | |
68 | + SDKGlobalConfiguration.IAM_ENDPOINT = COS_AUTH_ENDPOINT; | |
69 | + | |
70 | + final String apiKey = HybsSystem.sys("CLOUD_STORAGE_S3_APIKEY"); | |
71 | + final String serviceInstanceId = HybsSystem.sys("CLOUD_STORAGE_S3_SERVICEINSTANCEID"); | |
72 | + AWSCredentials credentials = new BasicIBMOAuthCredentials(apiKey, serviceInstanceId); | |
73 | + | |
74 | + final String serviceEndpoint = HybsSystem.sys("CLOUD_STORAGE_S3_SERVICE_END_POINT"); | |
75 | + final String signingRegion = HybsSystem.sys("CLOUD_STORAGE_S3_REGION"); | |
76 | + EndpointConfiguration endpointConfiguration = new EndpointConfiguration(serviceEndpoint, signingRegion); | |
77 | + | |
78 | + amazonS3 = AmazonS3ClientBuilder.standard() | |
79 | + .withCredentials(new AWSStaticCredentialsProvider(credentials)) | |
80 | + .withPathStyleAccessEnabled(true) | |
81 | + .withEndpointConfiguration(endpointConfiguration) | |
82 | + .build(); | |
83 | + | |
84 | + try { | |
85 | + if (!amazonS3.doesBucketExist(bucket)) { | |
86 | + amazonS3.createBucket(bucket); | |
87 | + } | |
88 | + } catch (AmazonS3Exception ase) { | |
89 | + StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
90 | + errMsg.append("アクセスキーによる認証が失敗しました。"); | |
91 | + errMsg.append(" CLOUD_STORAGE_S3_APIKEY:").append(apiKey); | |
92 | + errMsg.append(" CLOUD_STORAGE_S3_SERVICEINSTANCEID:").append(serviceInstanceId); | |
93 | + errMsg.append(" CLOUD_STORAGE_S3_SERVICE_END_POINT:").append(serviceEndpoint); | |
94 | + errMsg.append(" CLOUD_STORAGE_S3_REGION:").append(signingRegion); | |
95 | + errMsg.append(" システムエラー情報:").append(ase.getMessage()); | |
96 | + throw new HybsSystemException(errMsg.toString()); | |
97 | + } | |
98 | + } | |
99 | + | |
100 | + /** | |
101 | + * InputStreamのデータを書き込みます。 | |
102 | + * | |
103 | + * @param is 書き込みデータのInputStream | |
104 | + * @throws IOException | |
105 | + */ | |
106 | + @Override | |
107 | + public void write(InputStream is) throws IOException { | |
108 | + ByteArrayInputStream bais = null; | |
109 | + try { | |
110 | + ObjectMetadata om = new ObjectMetadata(); | |
111 | + | |
112 | + byte[] bytes = toByteArray(is); | |
113 | + om.setContentLength(bytes.length); | |
114 | + bais = new ByteArrayInputStream(bytes); | |
115 | + | |
116 | + PutObjectRequest request = new PutObjectRequest(bucket, path, bais, om); | |
117 | + | |
118 | + amazonS3.putObject(request); | |
119 | + } catch (Exception e) { | |
120 | + StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
121 | + errMsg.append("BLUEMIXバケットに書き込みが失敗しました。path:").append(path); | |
122 | + errMsg.append(" システムエラー情報:").append(e.getMessage()); | |
123 | + throw new IOException(errMsg.toString()); | |
124 | + } finally { | |
125 | + Closer.ioClose(bais); | |
126 | + } | |
127 | + } | |
128 | + | |
129 | + /** | |
130 | + * データを読み込み、InputStreamとして、返します。 | |
131 | + * | |
132 | + * @return 読み込みデータのInputStream | |
133 | + * @throws FileNotFoundException | |
134 | + */ | |
135 | + @Override | |
136 | + public InputStream read() throws FileNotFoundException { | |
137 | + S3Object object = null; | |
138 | + | |
139 | + try { | |
140 | + object = amazonS3.getObject(bucket, path); | |
141 | + } catch (Exception e) { | |
142 | + StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
143 | + errMsg.append("BLUEMIXバケットから読み込みが失敗しました。path:").append(path); | |
144 | + errMsg.append(" システムエラー情報:").append(e.getMessage()); | |
145 | + throw new FileNotFoundException(errMsg.toString()); | |
146 | + } | |
147 | + return object.getObjectContent(); | |
148 | + } | |
149 | + | |
150 | + /** | |
151 | + * ファイルを削除します。 | |
152 | + * | |
153 | + * @return 成否フラグ | |
154 | + */ | |
155 | + @Override | |
156 | + public boolean delete() { | |
157 | + boolean flgRtn = false; | |
158 | + | |
159 | + try { | |
160 | + if (isFile()) { | |
161 | + // ファイル削除 | |
162 | + amazonS3.deleteObject(bucket, path); | |
163 | + } else if (isDirectory()) { | |
164 | + // ディレクトリ削除 | |
165 | + // 一括削除のapiが無いので、繰り返しで削除を行う | |
166 | + ObjectListing objectList = amazonS3.listObjects(bucket, path); | |
167 | + List<S3ObjectSummary> list = objectList.getObjectSummaries(); | |
168 | + for (S3ObjectSummary obj : list) { | |
169 | + amazonS3.deleteObject(bucket, obj.getKey()); | |
170 | + } | |
171 | + | |
172 | + } | |
173 | + flgRtn = true; | |
174 | + } catch (Exception e) { | |
175 | + // エラーはスルーして、falseを返す | |
176 | + } | |
177 | + | |
178 | + return flgRtn; | |
179 | + } | |
180 | + | |
181 | + /** | |
182 | + * ファイルを指定先に、コピーします。 | |
183 | + * | |
184 | + * @param afPath コピー先 | |
185 | + * @return 成否フラグ | |
186 | + */ | |
187 | + @Override | |
188 | + public boolean copy(String afPath) { | |
189 | + boolean flgRtn = false; | |
190 | + | |
191 | + try { | |
192 | + amazonS3.copyObject(bucket, path, bucket, afPath); | |
193 | + flgRtn = true; | |
194 | + } catch (Exception e) { | |
195 | + // エラーはスルーして、falseを返す | |
196 | + } | |
197 | + | |
198 | + return flgRtn; | |
199 | + } | |
200 | + | |
201 | + /** | |
202 | + * ファイルサイズを返します | |
203 | + * | |
204 | + * @return ファイルサイズ | |
205 | + */ | |
206 | + @Override | |
207 | + public long length() { | |
208 | + long rtn = 0; | |
209 | + | |
210 | + try { | |
211 | + ObjectMetadata meta = amazonS3.getObjectMetadata(bucket, path); | |
212 | + rtn = meta.getContentLength(); | |
213 | + } catch (Exception e) { | |
214 | + // エラーはスルーして、0を返す。 | |
215 | + } | |
216 | + return rtn; | |
217 | + } | |
218 | + | |
219 | + /** | |
220 | + * 最終更新時刻を取得します。 | |
221 | + * | |
222 | + * @return 最終更新時刻 | |
223 | + */ | |
224 | + @Override | |
225 | + public long lastModified() { | |
226 | + long rtn = 0; | |
227 | + | |
228 | + try { | |
229 | + ObjectMetadata meta = amazonS3.getObjectMetadata(bucket, path); | |
230 | + rtn = meta.getLastModified().getTime(); | |
231 | + } catch (Exception e) { | |
232 | + // エラーはスルーして、0を返す | |
233 | + } | |
234 | + return rtn; | |
235 | + } | |
236 | + | |
237 | + /** | |
238 | + * ファイルの場合は、trueを返します。 | |
239 | + * | |
240 | + * @return ファイルフラグ | |
241 | + */ | |
242 | + @Override | |
243 | + public boolean isFile() { | |
244 | + return amazonS3.doesObjectExist(bucket, path); | |
245 | + } | |
246 | + | |
247 | + /** | |
248 | + * ディレクトリの場合は、trueを返します。 | |
249 | + * | |
250 | + * @return ディレクトリフラグ | |
251 | + */ | |
252 | + @Override | |
253 | + public boolean isDirectory() { | |
254 | + boolean flgRtn = false; | |
255 | + | |
256 | + if (StringUtils.isEmpty(path)) { | |
257 | + return true; | |
258 | + } | |
259 | + | |
260 | + // S3にはディレクトリの概念はないので、「/」で続くデータが存在するかで、判定 | |
261 | + ObjectListing objectList = amazonS3.listObjects(bucket, setDirTail(path)); | |
262 | + List<S3ObjectSummary> list = objectList.getObjectSummaries(); | |
263 | + flgRtn = list.size() == 0 ? false : true; | |
264 | + | |
265 | + return flgRtn; | |
266 | + } | |
267 | + | |
268 | + /** | |
269 | + * パスのファイルとディレクトリ一覧を取得します。 | |
270 | + * | |
271 | + * @return ファイルとティレクトリ一覧 | |
272 | + */ | |
273 | + @Override | |
274 | + public FileOperation[] listFiles(FileOperationFileFilter filter) { | |
275 | + if (!exists()) { | |
276 | + return new FileOperationInfo[0]; | |
277 | + } | |
278 | + | |
279 | + String search = path; | |
280 | + if (isDirectory()) { | |
281 | + search = setDirTail(path); | |
282 | + } | |
283 | + | |
284 | + List<FileOperationInfo> rtnList = new ArrayList<FileOperationInfo>(); | |
285 | + | |
286 | + // 検索処理 | |
287 | + ListObjectsV2Request request = new ListObjectsV2Request() | |
288 | + .withBucketName(bucket) | |
289 | + .withPrefix(search) | |
290 | + .withDelimiter("/"); | |
291 | + ListObjectsV2Result list = amazonS3.listObjectsV2(request); | |
292 | + List<S3ObjectSummary> objects = list.getObjectSummaries(); | |
293 | + | |
294 | + // ファイル情報の取得 | |
295 | + for (S3ObjectSummary obj : objects) { | |
296 | + String key = obj.getKey(); | |
297 | + | |
298 | + FileOperationInfo file = new FileOperationInfo(); | |
299 | + file.setPath(key); | |
300 | + file.setName(drawName(key)); | |
301 | + file.setParent(drawParent(key)); | |
302 | + file.setLastModified(obj.getLastModified().getTime()); | |
303 | + file.setFile(true); | |
304 | + file.setSize(obj.getSize()); | |
305 | + rtnList.add(file); | |
306 | + } | |
307 | + | |
308 | + // サブディレクトリ情報の取得 | |
309 | + List<String> folders = list.getCommonPrefixes(); | |
310 | + for (String str : folders) { | |
311 | + String key = rTrim(str, '/'); | |
312 | + | |
313 | + FileOperationInfo file = new FileOperationInfo(); | |
314 | + file.setPath(key); | |
315 | + file.setName(drawName(key)); | |
316 | + file.setParent(drawParent(key)); | |
317 | + file.setDirectory(true); | |
318 | + rtnList.add(file); | |
319 | + } | |
320 | + | |
321 | + // フィルタ処理 | |
322 | + FileOperation[] filterList = filter(rtnList, filter); | |
323 | + | |
324 | + return filterList; | |
325 | + } | |
326 | + | |
327 | + /** | |
328 | + * 親のディレクトリを返します。 | |
329 | + * | |
330 | + * @return 親のディレクトリ | |
331 | + */ | |
332 | + @Override | |
333 | + public FileOperation getParentFile() { | |
334 | + return new FileOperation_IBM(conBuket,getParent()); | |
335 | + } | |
336 | + | |
337 | + /** Bluemixの場合はローカル環境でのテストは出来ないようです。(proxyを設定しても接続できません) */ | |
338 | +} |
@@ -0,0 +1,406 @@ | ||
1 | +package org.opengion.plugin.cloud; | |
2 | + | |
3 | +import java.io.FileNotFoundException; | |
4 | +import java.io.IOException; | |
5 | +import java.io.InputStream; | |
6 | +import java.net.MalformedURLException; | |
7 | +import java.util.ArrayList; | |
8 | +import java.util.HashMap; | |
9 | +import java.util.List; | |
10 | +import java.util.Map; | |
11 | + | |
12 | +import org.apache.commons.lang3.StringUtils; | |
13 | +import org.opengion.fukurou.model.AbstractFileOperation; | |
14 | +import org.opengion.fukurou.model.FileOperation; | |
15 | +import org.opengion.fukurou.model.FileOperationFileFilter; | |
16 | +import org.opengion.fukurou.model.FileOperationInfo; | |
17 | +import org.opengion.fukurou.util.Closer; | |
18 | +import org.opengion.fukurou.util.StringUtil; | |
19 | +import org.opengion.hayabusa.common.HybsSystem; | |
20 | +import org.opengion.hayabusa.common.HybsSystemException; | |
21 | + | |
22 | +import oracle.cloud.storage.CloudStorage; | |
23 | +import oracle.cloud.storage.CloudStorageConfig; | |
24 | +import oracle.cloud.storage.CloudStorageFactory; | |
25 | +import oracle.cloud.storage.exception.NoSuchContainerException; | |
26 | +import oracle.cloud.storage.model.Key; | |
27 | +import oracle.cloud.storage.model.QueryOption; | |
28 | +import oracle.cloud.storage.model.QueryResult; | |
29 | + | |
30 | +/** | |
31 | + * FileOperation_ORACLE.javaは、Oracleクラウドのストレージに対して、 | |
32 | + * ファイル操作を行うクラスです。 | |
33 | + * | |
34 | + * @og.rev 5.10.8.0 (2019/02/01) 新規作成 | |
35 | + * | |
36 | + * @version 5 | |
37 | + * @author oota | |
38 | + * @since JDK7.0 | |
39 | + */ | |
40 | +public class FileOperation_ORACLE extends AbstractFileOperation { | |
41 | + /** クラス変数 */ | |
42 | + private final CloudStorage oracleStorage; | |
43 | + private final String conBuket; | |
44 | + | |
45 | + /** | |
46 | + * コンストラクター | |
47 | + * | |
48 | + * @param buket バケット | |
49 | + * @param inPath パス | |
50 | + */ | |
51 | + public FileOperation_ORACLE(String buket, String inPath) { | |
52 | + super(StringUtil.nval( buket, HybsSystem.sys("CLOUD_BUCKET") ),inPath); | |
53 | + conBuket = buket; | |
54 | + | |
55 | + CloudStorageConfig config = new CloudStorageConfig(); | |
56 | + | |
57 | + // リソースパラメータ設定 | |
58 | + // サービス名 | |
59 | + final String serviceName = HybsSystem.sys("CLOUD_STORAGE_ORACLE_SERVICE_NAME"); | |
60 | + // ユーザ名 | |
61 | + final String userName = HybsSystem.sys("CLOUD_STORAGE_ORACLE_USERNAME"); | |
62 | + // パスワード | |
63 | + final String password = HybsSystem.sys("CLOUD_STORAGE_ORACLE_PASSWORD"); | |
64 | + // サービスURL | |
65 | + final String serviceUrl = HybsSystem.sys("CLOUD_STORAGE_ORACLE_SERVICEURL"); | |
66 | + | |
67 | + initCheck(serviceName, userName, password, serviceUrl); | |
68 | + | |
69 | + try { | |
70 | + config.setServiceName(serviceName) | |
71 | + .setUsername(userName) | |
72 | + .setPassword(password.toCharArray()) | |
73 | + .setServiceUrl(serviceUrl); | |
74 | + | |
75 | + oracleStorage = CloudStorageFactory.getStorage(config); | |
76 | + | |
77 | + // コンテナの存在チェック | |
78 | + try { | |
79 | + oracleStorage.describeContainer(bucket); | |
80 | + }catch(NoSuchContainerException nce) { | |
81 | + // コンテナが存在しない場合は、作成する | |
82 | + oracleStorage.createContainer(bucket); | |
83 | + } | |
84 | + }catch(MalformedURLException me) { | |
85 | + throw new HybsSystemException(me.getMessage()); | |
86 | + } | |
87 | + } | |
88 | + | |
89 | + /** | |
90 | + * 初期チェック | |
91 | + */ | |
92 | + private void initCheck(String serviceName, String userName, String password, String serviceUrl){ | |
93 | + // システムリソースに認証情報が登録されていない場合は、エラー | |
94 | + StringBuilder errString = new StringBuilder(); | |
95 | + if(StringUtils.isEmpty(serviceName)){ | |
96 | + errString.append("CLOUD_STORAGE_ORACLE_SERVICE_NAME"); | |
97 | + } | |
98 | + if(StringUtils.isEmpty(userName)){ | |
99 | + errString.append(",CLOUD_STORAGE_ORACLE_USERNAME"); | |
100 | + } | |
101 | + if(StringUtils.isEmpty(password)){ | |
102 | + errString.append(",CLOUD_STORAGE_ORACLE_PASSWORD"); | |
103 | + } | |
104 | + if(StringUtils.isEmpty(serviceUrl)){ | |
105 | + errString.append(",CLOUD_STORAGE_ORACLE_SERVICEURL"); | |
106 | + } | |
107 | + | |
108 | + if(errString.length() > 0){ | |
109 | + throw new HybsSystemException("クラウドストレージのキー情報("+errString.toString()+")がシステムリソースに登録されていません。"); | |
110 | + } | |
111 | + | |
112 | + } | |
113 | + | |
114 | + /** | |
115 | + * InputStreamのデータを書き込みます。 | |
116 | + * | |
117 | + * @param is 書き込みデータのInputStream | |
118 | + * @throws IOException | |
119 | + */ | |
120 | + @Override | |
121 | + public void write(InputStream is) throws IOException { | |
122 | + try { | |
123 | + System.out.println("ora-path:" + path); | |
124 | + oracleStorage.storeObject(bucket, path, "application/octet-stream", is); | |
125 | + }catch(Exception e) { | |
126 | + StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
127 | + errMsg.append("Oracleストレージに書き込みが失敗しました。path:").append(path); | |
128 | + errMsg.append(" システムエラー情報:").append(e.getMessage()); | |
129 | + throw new IOException(errMsg.toString()); | |
130 | + } | |
131 | + } | |
132 | + | |
133 | + /** | |
134 | + * データを読み込み、InputStreamとして、返します。 | |
135 | + * | |
136 | + * @return 読み込みデータのInputStream | |
137 | + * @throws FileNotFoundException | |
138 | + */ | |
139 | + @Override | |
140 | + public InputStream read() throws FileNotFoundException { | |
141 | + InputStream is; | |
142 | + try { | |
143 | + is = oracleStorage.retrieveObject(bucket, path); | |
144 | + }catch(Exception e) { | |
145 | + StringBuilder errMsg = new StringBuilder(HybsSystem.BUFFER_MIDDLE); | |
146 | + errMsg.append("Oracleストレージから読み込みが失敗しました。path:").append(path); | |
147 | + errMsg.append(" システムエラー情報:").append(e.getMessage()); | |
148 | + throw new FileNotFoundException(errMsg.toString()); | |
149 | + } | |
150 | + return is; | |
151 | + } | |
152 | + | |
153 | + /** | |
154 | + * ファイルを削除します。 | |
155 | + * | |
156 | + * @return 成否フラグ | |
157 | + */ | |
158 | + @Override | |
159 | + public boolean delete() { | |
160 | + boolean flgRtn = false; | |
161 | + | |
162 | + try { | |
163 | + oracleStorage.deleteObject(bucket, path); | |
164 | + flgRtn = true; | |
165 | + }catch(Exception e) { | |
166 | + // エラーはスルーして、falseを返す | |
167 | + } | |
168 | + | |
169 | + return flgRtn; | |
170 | + } | |
171 | + | |
172 | + /** | |
173 | + * ファイルを指定先に、コピーします。 | |
174 | + * | |
175 | + * @param afPath コピー先 | |
176 | + * @return 成否フラグ | |
177 | + */ | |
178 | + @Override | |
179 | + public boolean copy(String afPath) { | |
180 | + boolean flgRtn = false; | |
181 | + InputStream is = null; | |
182 | + | |
183 | + try { | |
184 | + is = read(); | |
185 | + FileOperation_ORACLE afFile = new FileOperation_ORACLE(conBuket,afPath); | |
186 | + afFile.write(is); | |
187 | + flgRtn = true; | |
188 | + }catch(IOException ie) { | |
189 | + // エラーはスルーして、falseを返す | |
190 | + }finally { | |
191 | + Closer.ioClose(is); | |
192 | + } | |
193 | + | |
194 | + return flgRtn; | |
195 | + } | |
196 | + | |
197 | + /** | |
198 | + * ファイルサイズを返します | |
199 | + * | |
200 | + * @return ファイルサイズ | |
201 | + */ | |
202 | + @Override | |
203 | + public long length() { | |
204 | + long rtn = 0; | |
205 | + | |
206 | + try { | |
207 | + rtn = oracleStorage.describeObject(bucket, path).getSize(); | |
208 | + }catch(Exception e) { | |
209 | + // エラーはスルーして、0を返す | |
210 | + } | |
211 | + | |
212 | + return rtn; | |
213 | + } | |
214 | + | |
215 | + /** | |
216 | + * 最終更新時刻を取得します。 | |
217 | + * | |
218 | + * @return 最終更新時刻 | |
219 | + */ | |
220 | + @Override | |
221 | + public long lastModified() { | |
222 | + long rtn = 0; | |
223 | + | |
224 | + try { | |
225 | + rtn = oracleStorage.describeObject(bucket, path).getLastModified().getTime(); | |
226 | + }catch(Exception e) { | |
227 | + // エラーはスルーして、0を返す | |
228 | + } | |
229 | + | |
230 | + return rtn; | |
231 | + } | |
232 | + | |
233 | + /** | |
234 | + * ファイルの場合は、trueを返します。 | |
235 | + * | |
236 | + * @return ファイルフラグ | |
237 | + */ | |
238 | + @Override | |
239 | + public boolean isFile() { | |
240 | + boolean flgRtn = false; | |
241 | + | |
242 | + try { | |
243 | + oracleStorage.describeObject(bucket, path); | |
244 | + flgRtn = true; | |
245 | + }catch(Exception e) { | |
246 | + // ここでのエラーはスルーして、falseを返す | |
247 | + } | |
248 | + | |
249 | + return flgRtn; | |
250 | + } | |
251 | + | |
252 | + /** | |
253 | + * ディレクトリの場合は、trueを返します。 | |
254 | + * | |
255 | + * @return ディレクトリフラグ | |
256 | + */ | |
257 | + @Override | |
258 | + public boolean isDirectory() { | |
259 | + boolean blnRtn = false; | |
260 | + | |
261 | + if(StringUtil.isNull(path)) { | |
262 | + return true; | |
263 | + } | |
264 | + | |
265 | + Map<QueryOption, String> map = new HashMap<QueryOption, String>(); | |
266 | + map.put(QueryOption.PREFIX, setDirTail(path)); | |
267 | + | |
268 | + List<Key> list = oracleStorage.listObjects(bucket, map); | |
269 | + if(list.size() > 0) { | |
270 | + blnRtn = true; | |
271 | + } | |
272 | + | |
273 | + return blnRtn; | |
274 | + } | |
275 | + | |
276 | + /** | |
277 | + * パスのファイルとディレクトリ一覧を取得します。 | |
278 | + * | |
279 | + * @return ファイルとティレクトリ一覧 | |
280 | + */ | |
281 | + @Override | |
282 | + public FileOperation[] listFiles(FileOperationFileFilter filter){ | |
283 | + if(!exists()) { | |
284 | + return new FileOperationInfo[0]; | |
285 | + } | |
286 | + | |
287 | + String search = path; | |
288 | + if(isDirectory()) { | |
289 | + search = setDirTail(path); | |
290 | + } | |
291 | + | |
292 | + List<FileOperationInfo> rtnList = new ArrayList<FileOperationInfo>(); | |
293 | + | |
294 | + // 検索処理 | |
295 | + QueryResult result = oracleStorage.listObjectsByPath(bucket, "/", search, null); | |
296 | + | |
297 | + // ファイル情報の設定 | |
298 | + for(Key trg: result.getKeys()) { | |
299 | + String key = trg.getKey(); | |
300 | + | |
301 | + FileOperationInfo fi = new FileOperationInfo(); | |
302 | + fi.setPath(key); | |
303 | + fi.setName(drawName(key)); | |
304 | + fi.setParent(drawParent(key)); | |
305 | + fi.setLastModifiedValue(trg.getLastModified().getTime()); | |
306 | + fi.setSize(trg.getSize()); | |
307 | + fi.setFile(true); | |
308 | + rtnList.add(fi); | |
309 | + } | |
310 | + | |
311 | + // サブディレクトリ情報の設定 | |
312 | + for(String path: result.getPaths()) { | |
313 | + String key = rTrim(path, '/'); | |
314 | + | |
315 | + FileOperationInfo fi = new FileOperationInfo(); | |
316 | + fi.setPath(key); | |
317 | + fi.setName(drawName(key)); | |
318 | + fi.setParent(drawParent(key)); | |
319 | + fi.setDirectory(true); | |
320 | + rtnList.add(fi); | |
321 | + } | |
322 | + | |
323 | + FileOperation[] filterList = filter(rtnList, filter); | |
324 | + | |
325 | + return filterList; | |
326 | + } | |
327 | + | |
328 | + @Override | |
329 | + public FileOperation getParentFile() { | |
330 | + return new FileOperation_ORACLE(conBuket,getParent()); | |
331 | + } | |
332 | + | |
333 | + /** 以下はローカル環境でのテスト用メソッドです。 */ | |
334 | +// public FileOperation_ORACLE(String buket, String inPath, boolean test) { | |
335 | +// // super( StringUtil.nval( buket, HybsSystem.sys("CLOUD_BUCKET") ), inPath); | |
336 | +// super( StringUtil.nval( buket, "opengiontestbucket" ), inPath); | |
337 | +// conBuket = buket; | |
338 | +// | |
339 | +// // proxy設定 | |
340 | +// System.setProperty("https.proxyHost","mtc-px14"); | |
341 | +// System.setProperty("https.proxyPort","8081"); | |
342 | +// | |
343 | +// CloudStorageConfig config = new CloudStorageConfig(); | |
344 | +// // リソースパラメータ設定 | |
345 | +// final String serviceName = "[storage名]"; | |
346 | +// final String userName = "[userId]"; | |
347 | +// final String password = "[password]"; | |
348 | +// final String serviceUrl = "https://aucom-east-1.storage.oraclecloud.com"; | |
349 | +// | |
350 | +// initCheck(serviceName, userName, password, serviceUrl); | |
351 | +// | |
352 | +// try { | |
353 | +// config.setServiceName(serviceName) | |
354 | +// .setUsername(userName) | |
355 | +// .setPassword(password.toCharArray()) | |
356 | +// .setServiceUrl(serviceUrl); | |
357 | +// | |
358 | +// oracleStorage = CloudStorageFactory.getStorage(config); | |
359 | +// | |
360 | +// // コンテナの存在チェック | |
361 | +// try { | |
362 | +// oracleStorage.describeContainer(bucket); | |
363 | +// }catch(NoSuchContainerException nce) { | |
364 | +// // コンテナが存在しない場合は、作成する | |
365 | +// oracleStorage.createContainer(bucket); | |
366 | +// } | |
367 | +// }catch(MalformedURLException me) { | |
368 | +// throw new HybsSystemException(me.getMessage()); | |
369 | +// } | |
370 | +// } | |
371 | +// | |
372 | +// /** テスト用メソッド */ | |
373 | +// public static void main(String[] args) { | |
374 | +// // writeTest(); | |
375 | +// listTest(); | |
376 | +// // methodTest(); | |
377 | +// } | |
378 | +// | |
379 | +// public static void writeTest() { | |
380 | +// FileOperation file = new FileOperation_ORACLE("", "sample/test.txt", true); | |
381 | +// | |
382 | +// try (InputStream is = new ByteArrayInputStream("sample".getBytes())) { | |
383 | +// file.write(is); | |
384 | +// } catch (Exception e) { | |
385 | +// System.out.println(e.getMessage()); | |
386 | +// } | |
387 | +// } | |
388 | +// | |
389 | +// public static void listTest() { | |
390 | +// FileOperation file = new FileOperation_ORACLE("", "sample", true); | |
391 | +// | |
392 | +// FileOperation[] list = file.listFiles(); | |
393 | +// System.out.println(list.length); | |
394 | +// for (FileOperation f : list) { | |
395 | +// System.out.println(f.getPath()); | |
396 | +// } | |
397 | +// } | |
398 | +// | |
399 | +// public static void methodTest() { | |
400 | +// FileOperation file = new FileOperation_ORACLE("", "test", true); | |
401 | +// boolean rtn = false; | |
402 | +// rtn = file.isFile(); | |
403 | +// | |
404 | +// System.out.println(rtn); | |
405 | +// } | |
406 | +} |