001/*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016package org.opengion.hayabusa.io;
017
018import java.io.File;
019import java.util.function.Supplier;                                                             // 8.0.0.2 (2021/10/15)
020
021import org.opengion.fukurou.system.FileOperation;                               // 8.5.6.0 (2024/02/29) package変更 fukurou.model → fukurou.system
022import org.opengion.fukurou.system.FileOperationFactory;                // 8.5.6.0 (2024/02/29) package変更 fukurou.model → fukurou.system
023import org.opengion.fukurou.util.StringUtil;
024import org.opengion.fukurou.util.FileUtil;                                              // 8.0.0.2 (2021/10/15)
025import org.opengion.hayabusa.common.HybsSystem;
026// import org.opengion.fukurou.system.HybsConst;                                // 5.10.9.0 (2019/03/01)
027
028/**
029 * クラウドを含むファイル操作クラスの生成
030 *
031 * システムリソース参照のみで、クラウドクラスを生成します。(8.0.0.1 (2021/10/08)で固定)
032 * 引数付きの場合は、直接、org.opengion.fukurou.model.FileOperationFactory をご利用ください。
033 *
034 * 直接fukurouをCallしてもよいのですが、hayabusaからの呼び出しではシステムリソースを参照する必要があるため
035 * ラッパー的にこのクラスを経由してCallする事でシステムリソースが使われるようにしておきます。
036 * (タグ以外からも呼び出されるため、commonTagSupportではなく専用クラスをioパッケージに作成しています)
037 *
038 * ※ plugin → storage に変更。
039 *
040 * ローカルのファイルを扱いたい場合は、storageかbucketにLOCALを指定してください。
041 *
042 * @og.rev 5.10.8.0 (2019/02/01) 新規作成
043 * @og.rev 8.0.0.1 (2021/10/08) 修正対応
044 * @og.group
045 *
046 * @version 5.0
047 * @author Takahashi Masakazu
048 * @since JDK7.0
049 */
050public final class HybsFileOperationFactory {
051        private static final String STORAGE = HybsSystem.sys("CLOUD_TARGET");
052        private static final String BUCKET  = HybsSystem.sys("CLOUD_BUCKET");
053
054        /**
055         * デフォルトコンストラクターをprivateにして、
056         * オブジェクトの生成をさせないようにする。
057         */
058        private HybsFileOperationFactory(){
059                // コンストラクタ
060        }
061
062        /**
063         * fukurouのFileOperationFactoryを呼び出してFileOperationを取得します。
064         * storage,bucketを指定しない場合はシステムリソースを利用します。
065         *
066         * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加
067         *
068         * @param useLocal 強制的にローカルファイルを使用する場合、true にセットします。
069         * @param path ファイルパス
070         * @return FileOperationインスタンス
071         */
072        public static FileOperation create( final boolean useLocal,final String path ) {
073                final String bucket = useLocal ? FileOperation.LOCAL : BUCKET ;
074
075                return FileOperationFactory.newStorageOperation( STORAGE,bucket,path );
076        }
077
078        /**
079         * ディレクトリとファイル名を指定用です。
080         *
081         * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加
082         *
083         * @param useLocal 強制的にローカルファイルを使用する場合、true にセットします。
084         * @param dir ディレクトリパス
085         * @param fileName ファイル名
086         * @return FileOperationインスタンス
087         */
088        public static FileOperation create( final boolean useLocal,final String dir, final String fileName ) {
089                final String bucket = useLocal ? FileOperation.LOCAL : BUCKET ;
090                return FileOperationFactory.newStorageOperation( STORAGE,bucket,dir,fileName );         // 連結方法を統一します。
091        }
092
093        /**
094         * FileOperation(ディレクトリ)とファイル名を指定用です。
095         *
096         * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加
097         *
098         * @param useLocal 強制的にローカルファイルを使用する場合、true にセットします。
099         * @param dir ファイル(ディレクトリパス取得)
100         * @param fileName ファイル名
101         * @return FileOperationインスタンス
102         */
103        public static FileOperation create( final boolean useLocal,final File dir, final String fileName ) {
104                return create( useLocal,new File( dir,fileName ).getPath() );
105        }
106
107//      /**
108//       * fukurouのFileOperationFactoryを呼び出してFileOperationを取得します。
109//       * storage,bucketを指定しない場合はシステムリソースを利用します。
110//       *
111//       * @param storage ストレージ(AWS など)
112//       * @param bucket バケット名
113//       * @param path ファイルパス
114//       * @return FileOperationインスタンス
115//       */
116//      public static FileOperation create(final String storage, final String bucket, final String path) {
117//              return FileOperationFactory.newStorageOperation(
118//                              StringUtil.nval(storage, STORAGE), StringUtil.nval(bucket, BUCKET), path );
119//      }
120
121//      /**
122//       * FileOperation(ディレクトリ)とファイル名を指定用です。
123//       *
124//       * @param storage ストレージ(AWS など)
125//       * @param bucket バケット名
126//       * @param dir ファイル(ディレクトリパス取得)
127//       * @param filename ファイル名
128//       * @return FileOperationインスタンス
129//       */
130//      public static FileOperation create(final String storage, final String bucket, final File dir, final String filename) {
131//              return create(storage, bucket, new File( dir,filename ).getPath() );
132//      }
133
134//      /**
135//       * ディレクトリとファイル名を指定用です。
136//       *
137//       * @param storage ストレージ(AWS など)
138//       * @param bucket バケット名
139//       * @param dir ディレクトリパス
140//       * @param filename ファイル名
141//       * @return FileOperationインスタンス
142//       */
143//      public static FileOperation create(final String storage, final String bucket, final String dir, final String filename) {
144//              return create(storage, bucket, new File( dir,filename ).getPath() );
145//      }
146
147        /**
148         * システム定数で、クラウド設定されているかどうか
149         *
150         * システム定数の、CLOUD_TARGET か、CLOUD_BUCKET のどちらかが、
151         * null(ゼロ文字列、タブ、空白のみ)の場合、false です。
152         * それ以外は、true を返しますが、正常にクラウドにアクセス出来る保証はありません。
153         * あくまで、リソース設定がされているかどうかのみで、判定しています。
154         *
155         * @og.rev 8.0.0.1 (2021/10/08) クラウド修正
156         *
157         * @return クラウド設定されていれば true
158         */
159        public static boolean useCloud() {
160//              return ! StringUtil.isNull( STORAGE,BUCKET );   // どれか一つでも null なら、false
161
162                final boolean isLocal = StringUtil.isNull( STORAGE,BUCKET )
163                                                                || FileOperation.LOCAL.equalsIgnoreCase(STORAGE)
164                                                                || FileOperation.LOCAL.equalsIgnoreCase(BUCKET) ;
165
166                return ! isLocal ;
167        }
168
169        /**
170         * ローカルファイルをクラウドに移動<del>後、ローカルファイルを削除</del>します。
171         *
172         * クラウド設定されている場合、指定のサプライヤを実行してローカルファイルを取得し、
173         * クラウドにコピー後、ローカルファイルを削除します。
174         * クラウド設定されていなければ、何もしません。
175         *
176         * @og.rev 8.0.0.2 (2021/10/15) ローカルファイルとクラウドファイル間の移動
177         * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加、ファイル削除は行わない。
178         *
179         * @param useLocal 強制的にローカルファイルを使用する場合、true にセットします。
180         * @param supp ローカルファイルを生成するサプライヤ
181         */
182        public static void local2cloud( final boolean useLocal,final Supplier<File> supp ) {
183                if( !useLocal && useCloud() ) {
184                        final File localFile = supp.get();
185                        final FileOperation cloudFile = create( false,localFile.getPath() );
186                        FileUtil.copy( localFile, cloudFile );
187        //              localFile.delete();
188                }
189        }
190
191        /**
192         * クラウドファイルをローカルに移動<del>後、クラウドファイルを</del>削除します。
193         *
194         * クラウド設定されている場合、指定のサプライヤを実行してローカルファイルを取得し、
195         * まず、ローカルファイルを削除後、ローカルファイルの親フォルダを作成して、
196         * クラウドファイルをローカルに移動後、クラウドファイルを削除します。
197         * クラウド設定されていなければ、何もしません。
198         *
199         * @og.rev 8.0.0.2 (2021/10/15) ローカルファイルとクラウドファイル間の移動
200         * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加、ファイル削除は行わない。
201         *
202         * @param useLocal 強制的にローカルファイルを使用する場合、true にセットします。
203         * @param supp ローカルファイルを生成するサプライヤ
204         */
205        public static void cloud2local( final boolean useLocal,final Supplier<File> supp ) {
206                if( !useLocal && useCloud() ) {
207                        final File localFile = supp.get();
208                        final FileOperation cloudFile = create( false,localFile.getPath() );
209
210                        // 8.5.5.1 (2024/02/29) spotbugs RV_RETURN_VALUE_IGNORED_BAD_PRACTICE(例外的戻り値を無視しています)
211//                      localFile.delete();                                                                             // ファイルが最初から存在しない場合もfalse になる。
212                        if( localFile.exists() && !localFile.delete() ) {
213                                final String errMsg = "ローカルファイル を削除できませんでした。 localFile=[" + localFile + "]";
214                                System.out.println( errMsg );
215                        }
216
217                        final File localParent = localFile.getParentFile();
218                        // 8.5.5.1 (2024/02/29) spotbugs RV_RETURN_VALUE_IGNORED_BAD_PRACTICE(例外的戻り値を無視しています)
219//                      if( localParent != null ) { localParent.mkdirs(); }             // mkdirs が既に存在していると、false になる。
220                        if( localParent != null && !localParent.exists() && !localParent.mkdirs() ) {
221                                final String errMsg = "ローカルファイル の親フォルダの作成ができませんでした。localParent=[" + localParent + "]";
222                                System.out.println( errMsg );
223                        }
224
225                        FileUtil.copy( cloudFile, localFile );
226        //              cloudFile.delete();
227                }
228        }
229
230        /**
231         * #create(String,String,String)を呼び出してFileOperationを取得します。
232         * storage,bucketを指定しない場合はシステムリソースを利用します。
233         *
234         * 引数をディレクトリとして処理します。
235         * ローカルフォルダの場合、ディレクトリの作成、ディレクトリかどうかのチェック、書き込みチェックを行います。
236         *
237         * @og.rev 8.0.0.2 (2021/10/15) ローカルファイルとクラウドファイル間の移動
238         *
239//       * @param storage ストレージ(AWS など)
240//       * @param bucket バケット名
241         * @param useLocal 強制的にローカルファイルを使用する場合、true にセットします。
242         * @param dir ディレクトリパス
243         * @return FileOperationインスタンス
244         * @throws IllegalArgumentException 引数のディレクトリが作成できない、ディレクトリでない、書き込めない場合
245         * @see #create(boolean,String)
246         */
247//      public static FileOperation createDir(final String storage, final String bucket, final String dir) {
248        public static FileOperation createDir(final boolean useLocal, final String dir) {
249//              final FileOperation cloudDir = create( storage,bucket,dir );
250                final FileOperation cloudDir = create( useLocal,dir );
251
252//              if( !useCloud() ) {
253                if( useLocal || !useCloud() ) {
254                        // セーブディレクトリ 作成
255                        if( ! cloudDir.exists() && ! cloudDir.mkdirs() ) {
256                                throw new IllegalArgumentException( "Not make directory: " + dir );
257                        }
258
259                        // Check saveDirectory is truly a directory
260                        if(!cloudDir.isDirectory()) {
261                                throw new IllegalArgumentException("Not a directory: " + dir);
262                        }
263
264                        // Check saveDirectory is writable
265                        if(!cloudDir.canWrite()) {
266                                throw new IllegalArgumentException("Not writable: " + dir);
267                        }
268                }
269
270                return cloudDir ;
271        }
272}