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.taglib;
017
018import static org.opengion.fukurou.util.StringUtil.nval;
019
020import java.io.File;
021
022import org.opengion.fukurou.model.CloudFileOperation;
023import org.opengion.fukurou.model.FileOperation;
024import org.opengion.fukurou.util.FileUtil;
025import org.opengion.fukurou.util.StringUtil;
026import org.opengion.hayabusa.common.HybsSystem;
027import org.opengion.hayabusa.io.HybsFileOperationFactory;
028import org.opengion.hayabusa.report2.DocConverter_OOO;
029
030/**
031 * ドキュメントの変換・マージを行うタグです。
032 *
033 * 変換を行うことのできる入出力のフォーマット以下の通りです。
034 *
035 * [対応フォーマット]
036 *  入力[Calc(ods)   ,Excel(xls)     ] ⇒ 出力[Calc(ods)   ,Excel(xls)     ,PDF]
037 *  入力[Writer(odt) ,Word(doc)      ] ⇒ 出力[Writer(odt) ,Word(doc)      ,PDF]
038 *  入力[Impress(odp),PowerPoint(ppt)] ⇒ 出力[Impress(odp),PowerPoint(ppt),PDF]
039 *
040 * 入出力のフォーマットは、入出力ファイルの拡張子により自動判別されます。
041 * また、入出力ファイル名が同じ場合は何も処理されません。
042 *
043 * 入力ファイルを、カンマ区切りで複数指定することで、複数の入力ファイルをマージして
044 * 出力することもできます。
045 *
046 * ※2 現状は、ファイルのマージは、入力ファイルがExcelまたはCalcの場合のみ対応しています。
047 * ※1 この機能を利用するには、OpenOfficeが正しく設定されている必要があります。
048 *
049 * @og.formSample
050 * ●形式:<og:docConvert fileURL="…" inputFile="…" outputFile="…" />
051 * ●body:なし
052 *
053 * ●Tag定義:
054 *   <og:docConvert
055 *       fileURL            【TAG】操作するファイルのディレクトリを指定します (初期値:FILE_URL[=filetemp/])
056 *       inputFile        ○【TAG】入力ファイル名を指定します(必須)。
057 *       inputStorageType   【TAG】入力ファイルのストレージタイプを指定します。(初期値:CLOUD_TARGET)
058 *       inputBucketName     【TAG】入力ファイルのバケット名を指定します。(初期値:CLOUD_BUCKET)
059 *       outputFile       ○【TAG】出力ファイル名を指定します(必須)。
060 *       outputStorageType  【TAG】出力ファイルのストレージタイプを指定します。(初期値:CLOUD_TARGET)
061 *       outputBucketName    【TAG】出力ファイルのバケット名を指定します。(初期値:CLOUD_BUCKET)
062 *       delInput           【TAG】ドキュメント変換後、元のファイルを削除するかどうかを指定します(初期値:false[=削除しない])
063 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
064 *   />
065 *
066 * ●使用例
067 *    ・Calc(ods)ファイルをPDFに変換
068 *        <og:docConvert inputFile="temp.ods" outputFile="out.pdf" />
069 *
070 *    ・Excel(xls)ファイルを連結
071 *        <og:docConvert inputFile="temp1.xls,temp2.xls" outputFile="out.xls" />
072 *
073 * @og.rev 5.10.9.0 (2019/03/01) oota クラウドストレージ対応を追加。(Fileクラスを拡張)
074 * 
075 * @og.group その他部品
076 *
077 * @version  4.0
078 * @author       Hiroki Nakamura
079 * @since    JDK5.0,
080 */
081public class DocConvertTag extends CommonTagSupport {
082        //* このプログラムのVERSION文字列を設定します。   {@value} */
083        private static final String VERSION = "5.1.6.0 (2010/05/06)" ;
084
085        private static final long serialVersionUID = 516020100506L ;
086
087        private String  fileURL         = HybsSystem.sys( "FILE_URL" );
088        private String[]inputFile       = null;
089        private String  outputFile      = null;
090        private boolean delInput        = false;
091        private String  inputStorageType        = null;         // 5.10.9.0 (2019/03/01) ADD
092        private String  inputBucketName         = null;         // 5.10.9.0 (2019/03/01) ADD
093        private String  outputStorageType       = null;         // 5.10.9.0 (2019/03/01) ADD
094        private String  outputBucketName                = null;         // 5.10.9.0 (2019/03/01) ADD
095
096        /**
097         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
098         *
099         * @return      後続処理の指示( SKIP_BODY )
100         */
101        @Override
102        public int doStartTag() {
103                return ( SKIP_BODY );
104        }
105
106        /**
107         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
108         *
109         * @return      後続処理の指示
110         */
111        @Override
112        public int doEndTag() {
113                debugPrint();
114
115                // 出力ファイルで拡張子だけが指定された場合は、入力ファイル名を付加する
116                if( outputFile.indexOf( '.' ) < 0 ) {
117                        int inSufIdx = inputFile[0].lastIndexOf( '.' );
118                        if( inSufIdx >= 0 ) {
119                                outputFile = inputFile[0].substring( 0, inSufIdx ) + "." + outputFile;
120                        }
121
122                }
123
124                String directory = HybsSystem.url2dir( fileURL );
125                String[] input = new String[inputFile.length];
126                for( int i=0; i<input.length; i++ ) {
127                        input[i] = StringUtil.urlAppend( directory,inputFile[i] );
128                }
129                String output = StringUtil.urlAppend( directory,outputFile );
130
131                FileOperation inFile = HybsFileOperationFactory.create(null, null, input[0]);
132                
133                // 5.10.9.0 (2019/03/01) ADD クラウドストレージ指定の場合、ファイルをローカルにダウンロードします。
134                if(!inFile.isLocal()) {
135                        for(String in: input) {
136                                File fromFile = HybsFileOperationFactory.create(inputStorageType, inputBucketName, in);
137                                File toFile = new File(in);
138                                // toFileのディレクトリを作成する必要あり?
139                                FileUtil.copy(fromFile, toFile);
140                        }
141                }
142                
143                // ドキュメント変換
144                DocConverter_OOO.convert( input, output );
145
146                // 5.10.9.0 (2019/03/01) ADD クラウドストレージ指定の場合、ファイルをクラウドストレージにアップロードします。
147                FileOperation outFile = HybsFileOperationFactory.create(outputStorageType, outputBucketName, output);
148                if(!outFile.isLocal()) {
149                        File localFile = new File(output); 
150                        FileUtil.copy(localFile, outFile);
151                        localFile.delete();
152                }
153                
154                if( delInput ) {
155                        for( int i=0; i<input.length; i++ ) {
156                                if( !( new File( input[i] ) ).delete() ) {
157                                        System.err.println( "入力ファイルの削除に失敗しました。file=[" + input[i] + "]" );
158                                }
159                        }
160                }
161
162                return( EVAL_PAGE );
163        }
164
165        /**
166         * タグリブオブジェクトをリリースします。
167         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
168         *
169         */
170        @Override
171        protected void release2() {
172                super.release2();
173                fileURL         = HybsSystem.sys( "FILE_URL" );
174                inputFile       = null;
175                outputFile      = null;
176                delInput        = false;
177                inputStorageType        = null;         // 5.10.9.0 (2019/03/01) ADD
178                inputBucketName         = null;         // 5.10.9.0 (2019/03/01) ADD
179                outputStorageType       = null;         // 5.10.9.0 (2019/03/01) ADD
180                outputBucketName                = null;         // 5.10.9.0 (2019/03/01) ADD
181        }
182
183        /**
184         * 【TAG】操作するファイルのディレクトリを指定します
185         *              (初期値:FILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])。
186         *
187         * @og.tag
188         * この属性で指定されるディレクトリのファイルを操作します。
189         * 指定方法は、通常の fileURL 属性と同様に、先頭が、'/' (UNIX) または、2文字目が、
190         * ":" (Windows)の場合は、指定のURLそのままのディレクトリに、そうでない場合は、
191         * (初期値:システム定数のFILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])。
192         *
193         * @param       url ファイルURL
194         * @see         org.opengion.hayabusa.common.SystemData#FILE_URL
195         */
196        public void setFileURL( final String url ) {
197                String furl = nval( getRequestParameter( url ),null );
198                if( furl != null ) {
199                        char ch = furl.charAt( furl.length()-1 );
200                        if( ch != '/' && ch != '\\' ) { furl = furl + "/"; }
201                        fileURL = StringUtil.urlAppend( fileURL,furl );
202                }
203        }
204
205        /**
206         * 【TAG】入力ファイル名を指定します。
207         *
208         * @og.tag
209         * 入力ファイル名を指定します。
210         *
211         * 入力ファイルは、カンマ区切りで複数指定することができます。
212         * この場合、複数の入力ファイルをマージして出力を行います。
213         *
214         * ※現状は、ファイルのマージは、入力ファイルがExcelまたはCalcの場合のみ対応しています。
215         *   また、マージを行う場合、印刷範囲など、ドキュメントに関連する情報は、1つ目のファイルの
216         *   情報が使用されます。
217         *
218         * @param       fname 入力ファイル名
219         */
220        public void setInputFile( final String fname ) {
221                inputFile = getCSVParameter( fname );
222        }
223
224        /**
225         * 【TAG】出力ファイル名を指定します。
226         *
227         * @og.tag
228         * 出力ファイル名を指定します。
229         * 出力ファイルには、拡張子のみ(xls,ods等)を指定することもできます。
230         * この場合、出力ファイル名は、入力ファイル名と同じになります。(拡張子のみが変換される)
231         *
232         * @param       fname 出力ファイル名
233         */
234        public void setOutputFile( final String fname ) {
235                outputFile = nval( getRequestParameter( fname ),outputFile );
236        }
237
238        /**
239         * 【TAG】ドキュメント変換後、元のファイルを削除するかどうかを指定します(初期値:false[=削除しない])。
240         *
241         * @og.tag
242         * ドキュメント変換後、元のファイルを削除するかどうかを指定します。
243         * (初期値:false(削除しない))
244         *
245         * @param       flg 出力元のファイルを削除するかどうか名
246         */
247        public void setDelInput( final String flg ) {
248                delInput = nval( getRequestParameter( flg ),delInput );
249        }
250
251        /**
252         * 【TAG】読み取り元ストレージタイプを設定します。
253         *  
254         * @og.tag
255         * ファイルを読み取り元の、ストレージタイプを設定します。
256         * 未設定の場合は、システムリソースの「CLOUD_TARGET」が参照されます。
257         * 自身のサーバを指定する場合は、「default」を設定してください。
258         * 
259         * @og.rev 5.10.9.0 (2019/03/01) 新規追加
260         * 
261         * @param inStorage ストレージタイプ
262         */
263        public void setInputStorageType( final String inStorage ) {
264                inputStorageType = nval( getRequestParameter( inStorage ), inputStorageType );
265        }
266        
267        /**
268         * 【TAG】読み取り元バケット名を設定します。
269         * 
270         * @og.tag
271         * ファイルを読み取り元の、バケット名を指定します。
272         * クラウドストレージ利用時のみ有効です。
273         * 未設定の場合は、システムリソースの「CLOUD_BUKET」が参照されます。
274         * 
275         * @og.rev 5.10.9.0 (2019/03/01) 新規追加
276         * 
277         * @param inBucket バケット名
278         */
279        public void setInputBucketName( final String inBucket ) {
280                inputBucketName = nval( getRequestParameter( inBucket ), inputBucketName );
281        }
282        
283        /**
284         * 【TAG】保存先ストレージタイプを設定します。
285         *  
286         * @og.tag
287         * ファイルを保存するストレージタイプを設定します。
288         * 未設定の場合は、システムリソースの「CLOUD_TARGET」が参照されます。
289         * 自身のサーバを指定する場合は、「default」を設定してください。
290         * 
291         * @og.rev 5.10.9.0 (2019/03/01) 新規追加
292         * 
293         * @param outStorage ストレージタイプ
294         */
295        public void setOutputStorageType( final String outStorage ) {
296                outputStorageType = nval( getRequestParameter( outStorage ), outputStorageType );
297        }
298        
299        /**
300         * 【TAG】保存先バケット名を設定します。
301         * 
302         * @og.tag
303         * ファイルを保存するバケット名を指定します。
304         * クラウドストレージ利用時のみ有効です。
305         * 未設定の場合は、システムリソースの「CLOUD_BUKET」が参照されます。
306         * 
307         * @og.rev 5.10.9.0 (2019/03/01) 新規追加
308         * 
309         * @param outBucket バケット名
310         */
311        public void setOutputBucketName(final String outBucket ) {
312                this.outputBucketName = nval( getRequestParameter( outBucket ), outputBucketName );;
313        }
314        
315        /**
316         * このオブジェクトの文字列表現を返します。
317         * 基本的にデバッグ目的に使用します。
318         *
319         * @og.rev 5.10.9.0 (2019/03/01) inputStorageType,inputBucketName, outputStorageType,outputBucketNameを属性に追加。
320         * 
321         * @return このクラスの文字列表現
322         */
323        @Override
324        public String toString() {
325                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
326                                .println( "VERSION"             ,VERSION        )
327                                .println( "fileURL"             ,fileURL        )
328                                .println( "inputFile"   ,inputFile              )
329                                .println( "outputFile"  ,outputFile             )
330                                .println( "inputStorageType",   inputStorageType        )
331                                .println( "inputBucketName",            inputBucketName         )
332                                .println( "outputStorageType",  outputStorageType       )
333                                .println( "outputBucketName",   outputBucketName                )
334                                .println( "Other..."    ,getAttributes().getAttribute() )
335                                .fixForm().toString() ;
336        }
337}