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 org.opengion.hayabusa.common.HybsSystem;
019import org.opengion.hayabusa.common.HybsSystemException;
020import org.opengion.hayabusa.db.DBTableModel;
021import org.opengion.hayabusa.report.DBTableReport;
022import org.opengion.fukurou.util.FileUtil;
023import org.opengion.fukurou.util.Shell;
024
025import org.opengion.fukurou.util.StringUtil ;
026import static org.opengion.fukurou.util.StringUtil.nval ;
027
028import java.io.File;
029import java.io.IOException;
030import java.io.ObjectOutputStream;
031import java.io.ObjectInputStream;
032
033/**
034 * 検索結果の DBTableModelオブジェクトをレポート形式に変換するタグです。
035 *
036 * データ(DBTableModel)と、コントローラ(DBTableReport クラス)を与えて、
037 * 外部からコントロールすることで、各種形式で データ(DBTableModel)を表示させることが
038 * 可能です。
039 *
040 * @og.formSample
041 * ●形式:<og:report fileURL="[・・・]" listId="[・・・]" ・・・ />
042 * ●body:なし
043 *
044 * ●Tag定義:
045 *   <og:report
046 *       listId           ○【TAG】帳票IDを指定します(必須)。
047 *       fileURL            【TAG】雛型のHTMLファイルの保存してある ディレクトリを指定します
048 *       programFile        【TAG】HTMLファイルをEXCEL変換する場合に使用するBATファイルを指定します
049 *       outFileURL         【TAG】出力HTMLファイルの保存してあるディレクトリを指定します
050 *       outFilename      ○【TAG】ファイルを作成するときの出力ファイル名をセットします(必須)。
051 *       headerKeys         【TAG】固定部の{@KEY} の KEY 部分をCSV形式で複数指定します
052 *       headerVals         【TAG】固定部のKEY に対応する値をCSV形式で複数指定します
053 *       footerKeys         【TAG】繰り返し部の終了後に表示する key 部分をCSV形式で複数指定します
054 *       footerVals         【TAG】固定部のKEY に対応する値をCSV形式で複数指定します
055 *       pageEndCut         【TAG】ボディー部(繰り返し部)がなくなったときに、それ以降を表示するかどうか[true/false]を指定します(初期値:true)
056 *       reportClass        【TAG】実際に書き出すクラス名の略称(DBTableReport_**** の ****)をセットします(初期値:HTML)
057 *       language           【TAG】タグ内部で使用する言語コード[ja/en/zh/…]を指定します
058 *       scope              【TAG】キャッシュする場合のスコープ[request/page/session/applicaton]を指定します(初期値:session)
059 *       tableId            【TAG】(通常使いません)sessionから所得する DBTableModelオブジェクトの ID
060 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
061 *   />
062 *
063 * ●使用例
064 *
065 * @og.group その他出力
066 *
067 * @version  4.0
068 * @author   Kazuhiko Hasegawa
069 * @since    JDK5.0,
070 */
071public class ReportTableTag extends CommonTagSupport {
072        //* このプログラムのVERSION文字列を設定します。   {@value} */
073        private static final String VERSION = "4.0.0.0 (2007/11/28)" ;
074
075        private static final long serialVersionUID = 400020071128L ;
076
077        // 印刷時に使用するテンポラリフォルダ名
078        private final String REPORT_URL =
079                nval( HybsSystem.sys( "REPORT_FILE_URL" ) ,
080                                 HybsSystem.sys( "FILE_URL" ) + "REPORT/" ) ;
081
082        // 3.8.0.4 (2005/08/08) 印刷時に使用するシステムID
083        private static final String SYSTEM_ID =HybsSystem.sys( "SYSTEM_ID" );
084
085        // 3.8.0.4 (2005/08/08) 帳票出力に準拠した方式に変更
086        private final int TIMEOUT = HybsSystem.sysInt( "REPORT_DAEMON_TIMEOUT" );
087
088        private final String  BASE_URL  = HybsSystem.sys( "FILE_URL" );
089
090        private String[]  headerKeys    = null;   // 固定部の{@KEY} の KEY 部分を指定する。カンマで複数指定できる。
091        private String[]  headerVals    = null;   // 固定部のKEY に対応する値を指定する。 {@KEY} に置き換わる。
092        private String[]  footerKeys    = null;   // 繰り返し部の終了後に表示する key 部分を指定する。カンマで複数指定できる。
093        private String[]  footerVals    = null;   // 繰り返し部の終了後に表示する key に対する値を指定する。
094        private boolean   pageEndCut    = true;   // ボディー部(繰り返し部)がなくなったときに、それ以降のページを出力するか指定する。
095        private String    fileURL               = BASE_URL;             // 雛型のHTMLファイルの保存してある ディレクトリを指定します。
096        private String    outFileURL    = BASE_URL;             // 出力HTMLファイルの保存してある ディレクトリを指定します。
097        private String    outFilename   = null;                 // 出力HTMLファイル名を指定します。 ディレクトリ名を含んでも構いません。
098        private String    reportClass   = "HTML";
099
100        private transient DBTableModel table    = null;
101        private String  tableId                 = HybsSystem.TBL_MDL_KEY ;
102        // 3.8.0.4 (2005/08/08) 帳票出力に準拠した方式に変更
103        private String  listId                  = null ;        // 雛型のHTMLファイル名を指定します。
104        private String  programFile             = null;         // HTMLファイルのEXCEL化を行うバッチファイルを指定します。
105
106        /**
107         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
108         *
109         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
110         * @og.rev 3.8.0.4 (2005/08/08) 帳票出力に準拠した方式に変更
111         * @og.rev 4.0.0.0 (2007/10/18) メッセージリソース統合( getResource().getMessage ⇒ getResource().getLabel )
112         * @og.rev 4.0.0.0 (2007/11/28) メソッドの戻り値をチェックします。
113         *
114         * @return      後続処理の指示
115         */
116        @Override
117        public int doEndTag() {
118                debugPrint();
119
120                final int rtnCode;
121
122                table = (DBTableModel)getObject( tableId );
123                if( table == null || table.getRowCount() == 0 ) {
124                        rtnCode = SKIP_PAGE ;           // ページの残りの処理を行わない。
125                }
126                else {
127                        synchronized( ReportTableTag.class ) {
128                                String reportDir  = HybsSystem.url2dir( REPORT_URL ) + SYSTEM_ID + HybsSystem.FS + listId ;
129                //              String ykno       = HybsSystem.getDate( "yyyyMMddHHmmss" );
130                                String ykno       = String.valueOf( Math.round( Math.random() * 1000000 ) ) ;
131
132                                create( reportDir,ykno ) ;
133
134                                // 処理クラス(reportClass)が HTML の場合は、Shell を起動して、VBS で EXCEL化が必要。
135                                if( programFile != null && "HTML".equalsIgnoreCase( reportClass ) ) {
136                                        String htmlFile = reportDir + HybsSystem.FS + ykno ;
137                                        String cmd = makeShellCommand( htmlFile,listId );
138                                        programRun( cmd );
139                                }
140
141                                if( outFilename != null ) {
142                                        File xlsFile = new File( reportDir,ykno + ".xls" );
143                                        File outDir  = new File( HybsSystem.url2dir( outFileURL ) );
144                                        if( !outDir.exists() && !outDir.mkdirs() ) {
145                                                String errMsg = "所定のフォルダを作成できませんでした。[" + outDir + "]" ;
146                                                throw new RuntimeException( errMsg );
147                                        }
148                                        File outFile = new File( outDir,outFilename );
149                                        FileUtil.copy(  xlsFile , outFile );
150
151                                        String msg = getResource().getLabel( "MSG0003" )                // MSG0003=ファイルの登録が完了しました。
152                                                                + HybsSystem.BR
153                                                                + getResource().getLabel( "MSG0022" )   // MSG0022=ファイル名
154                                                                + ":" + outFile.getAbsolutePath() ;
155                                        jspPrint( msg );
156                                }
157                        }
158                        rtnCode = EVAL_PAGE ;
159                }
160
161                return rtnCode ;
162        }
163
164        /**
165         * タグリブオブジェクトをリリースします。
166         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
167         *
168         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
169         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
170         * @og.rev 3.1.3.0 (2003/04/10) REPORT_ENCODE(帳票エンコーディング)を利用するように修正。
171         * @og.rev 3.8.0.4 (2005/08/08) filename 削除、listId ,programFile 追加 ,
172         *
173         */
174        @Override
175        protected void release2() {
176                super.release2();
177                headerKeys              = null;
178                headerVals              = null;
179                footerKeys              = null;
180                footerVals              = null;
181                pageEndCut              = true;
182                fileURL                 = BASE_URL;
183                outFileURL              = BASE_URL;
184                outFilename             = null;                 // 出力ファイル名
185                reportClass             = "HTML";
186                table                   = null;
187                tableId                 = HybsSystem.TBL_MDL_KEY ;
188                listId                  = null ;                // 3.8.0.4 (2005/08/08)
189                programFile             = null ;                // 3.8.0.4 (2005/08/08)
190        }
191
192        /**
193         * TableWriter の実オブジェクトを生成して,PrintWriter に書き込みます。
194         *
195         * @og.rev 3.1.3.0 (2003/04/10) REPORT_ENCODE(帳票エンコーディング)を利用するように修正。
196         * @og.rev 3.5.4.3 (2004/01/05) HTMLDBTableReport のクラス名変更。
197         * @og.rev 3.6.0.0 (2004/09/17) メソッド名の変更。setInputFile ⇒ setTemplateFile
198         * @og.rev 3.8.0.0 (2005/06/07) setTemplateFile メソッドの引数を String  ⇒ File に変更
199         * @og.rev 3.8.0.4 (2005/08/08) 帳票出力に準拠した方式に変更
200         * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更
201         *
202         * @param       reportDir       出力ディレクトリ名
203         * @param       ykno            要求番号
204         */
205        private void create( final String reportDir,final String ykno )  {
206
207                String className = "org.opengion.hayabusa.report.DBTableReport_" + reportClass  ;
208                DBTableReport report = (DBTableReport)HybsSystem.newInstance( className );      // 3.5.5.3 (2004/04/09)
209
210                String MODELDIR = HybsSystem.url2dir( fileURL ) ;
211
212                File templateFile      = null;
213                File firstTemplateFile = null;
214
215                // 本来は、各クラス中で処理すべき。そのためのオブジェクト指向なのだから。
216                if( "HTML".equalsIgnoreCase( reportClass ) ) {
217                        templateFile      = FileUtil.checkFile( MODELDIR, listId + ".html" , 1 );
218                        firstTemplateFile = FileUtil.checkFile( MODELDIR, listId + "_FIRST.html" ,1 );
219                }
220                else if( "Excel".equalsIgnoreCase( reportClass ) ) {
221                        templateFile      = FileUtil.checkFile( MODELDIR, listId + ".xls" , 1 );
222                }
223                else {
224                        String errMsg = "リポートクラスがサポート外です。[" + reportClass + "]"
225                                                + "クラスは、HTML、Excel のみサポートされています。" ;
226                        throw new RuntimeException( errMsg );
227                }
228
229                FileUtil.copy( templateFile,new File( reportDir ) );
230
231                report.setDBTableModel( table );
232                report.setTemplateFile( templateFile ); // 3.6.0.0 (2004/09/17)
233                report.setFirstTemplateFile( firstTemplateFile );       // 3.6.0.0 (2004/09/17)
234                report.setOutputDir( reportDir );
235                report.setOutputFileKey( ykno );
236                report.setHeaderKeys( headerKeys );
237                report.setHeaderVals( headerVals );
238                report.setFooterKeys( footerKeys );
239                report.setFooterVals( footerVals );
240                report.setPageEndCut( pageEndCut );
241                report.setResourceManager( getResource() );     // 4.0.0 (2005/01/31)
242                report.setListId( listId );             // 3.6.1.0 (2005/01/05)
243                report.writeReport();
244        }
245
246        /**
247         * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
248         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。
249         *
250         * @og.tag
251         * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に
252         * 渡す場合に、通常は、session を利用します。その場合の登録キーです。
253         * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、
254         * この tableId 属性を利用して、メモリ空間を分けます。
255         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。
256         *
257         * @param       id sessionに登録する時の ID
258         */
259        public void setTableId( final String id ) {
260                tableId = nval( getRequestParameter( id ), tableId );
261        }
262
263        /**
264         * 【TAG】帳票IDを指定します。
265         *
266         * @og.tag
267         * 雛形ファイルは、帳票ID.html となります。また、ファーストページ対応の場合は、
268         * 帳票ID_FIRST.html になります。
269         * なお、filename 属性が指定された場合は、そちらが優先されます。
270         *
271         * @og.rev 3.8.0.4 (2005/08/08) 新規追加
272         *
273         * @param       listId  帳票ID
274         */
275        public void setListId( final String listId ) {
276                this.listId = nval( getRequestParameter( listId ), this.listId );
277        }
278
279        /**
280         * 【TAG】固定部の{@KEY} の KEY 部分をCSV形式で複数指定します。
281         *
282         * @og.tag
283         * カンマで複数指定できます。
284         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
285         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
286         *
287         * @og.rev 3.5.6.2 (2004/07/05) 先に配列に分解してからリクエスト変数の値を取得
288         *
289         * @param   hKeys 固定部の key
290         */
291        public void setHeaderKeys( final String hKeys ) {
292                headerKeys = getCSVParameter( hKeys );
293        }
294
295        /**
296         * 【TAG】固定部のKEY に対応する値をCSV形式で複数指定します。
297         *
298         * @og.tag
299         * カンマで複数指定で、リクエスト情報でも設定できます。
300         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
301         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
302         *
303         * @og.rev 3.5.6.2 (2004/07/05) 先に配列に分解してからリクエスト変数の値を取得
304         *
305         * @param   hVals 固定部の値
306         */
307        public void setHeaderVals( final String hVals ) {
308                headerVals = getCSVParameter( hVals );
309        }
310
311        /**
312         * 【TAG】繰り返し部の終了後に表示する key 部分をCSV形式で複数指定します。
313         *
314         * @og.tag
315         * カンマで複数指定できます。
316         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
317         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
318         *
319         * @og.rev 3.5.6.2 (2004/07/05) 先に配列に分解してからリクエスト変数の値を取得
320         *
321         * @param   ftKeys 繰り返し部の終了後に表示する key
322         */
323        public void setFooterKeys( final String ftKeys ) {
324                footerKeys = getCSVParameter( ftKeys );
325        }
326
327        /**
328         * 【TAG】固定部のKEY に対応する値をCSV形式で複数指定します。
329         *
330         * @og.tag
331         * カンマで複数指定で、リクエスト情報でも設定できます。
332         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
333         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
334         *
335         * @og.rev 3.5.6.2 (2004/07/05) 先に配列に分解してからリクエスト変数の値を取得
336         * @og.rev 3.8.1.2 (2005/12/19) footer 関連の値とpageEndCut の関係を解除します。
337         *
338         * @param   ftVals 繰り返し部の終了後に表示する値
339         */
340        public void setFooterVals( final String ftVals ) {
341                footerVals = getCSVParameter( ftVals );
342        }
343
344        /**
345         * 【TAG】ボディー部(繰り返し部)がなくなったときに、それ以降を表示するかどうか[true/false]を指定します(初期値:true)。
346         *
347         * @og.tag
348         * true では、それ以降を出力しません。
349         * 初期値は "true" (なくなった時点で、出力しない。)です。
350         *
351         * @og.rev 3.8.1.2 (2005/12/19) footer 関連の値とpageEndCut の関係を解除します。
352         *
353         * @param   peCut 繰り返し部の終了後に継続処理するかどうか (true:処理しない/false:処理する)
354         */
355        public void setPageEndCut( final String peCut ) {
356                pageEndCut = nval( getRequestParameter( peCut ),pageEndCut );
357        }
358
359        /**
360         * 【TAG】雛型のHTMLファイルの保存してある ディレクトリを指定します。
361         *
362         * @og.tag
363         * この属性で指定されるディレクトリのファイルを読み取ります。
364         * 指定方法は、通常の fileURL 属性と同様に、先頭が、'/' (UNIX) または、2文字目が、
365         * ":" (Windows)の場合は、指定のURLそのままのディレクトリに、そうでない場合は、
366         * システムパラメータ の FILE_URL 属性で指定のフォルダの下に、作成されます。
367         * fileURL = "{@USER.ID}" と指定すると、FILE_URL 属性で指定のフォルダの下に、
368         * さらに、各個人ID別のフォルダを作成して、そこを操作します。
369         *
370         * @og.rev 4.0.0.0 (2005/01/31) StringUtil.urlAppend メソッドの利用
371         * @og.rev 4.0.0.0 (2007/11/20) 指定されたディレクトリ名の最後が"\"or"/"で終わっていない場合に、"/"を付加する。
372         *
373         * @param       url 雛型のHTMLファイルのディレクトリ
374         */
375        public void setFileURL( final String url ) {
376                String furl = nval( getRequestParameter( url ),null );
377                if( furl != null ) {
378                        char ch = furl.charAt( furl.length()-1 );
379                        if( ch != '/' && ch != '\\' ) { furl = furl + "/"; }
380                        fileURL = StringUtil.urlAppend( fileURL,furl );
381                }
382        }
383
384        /**
385         * 【TAG】HTMLファイルをEXCEL変換する場合に使用するBATファイルを指定します。
386         *
387         * @og.tag
388         * ファイルは、フルパスで指定してください。
389         * 指定がない場合は、変換処理は行いません。
390         * 通常は、dbdef2/def/Script/runExcelPrint.bat を呼び出してください。
391         * 初期値は、null(変換処理しない)です。
392         *
393         * @og.rev 3.8.0.4 (2005/08/08) 新規追加
394         *
395         * @param   programFile プログラムファイル名
396         */
397        public void setProgramFile( final String programFile ) {
398                this.programFile = nval( getRequestParameter( programFile ),this.programFile );
399        }
400
401        /**
402         * 【TAG】出力HTMLファイルの保存してあるディレクトリを指定します。
403         *
404         * @og.tag
405         * この属性で指定されるディレクトリにファイルを出力します。
406         * 指定方法は、通常の fileURL 属性と同様に、先頭が、'/' (UNIX) または、2文字目が、
407         * ":" (Windows)の場合は、指定のURLそのままのディレクトリに、そうでない場合は、
408         * システムパラメータ の FILE_URL 属性で指定のフォルダの下に、作成されます。
409         * fileURL = "{@USER.ID}" と指定すると、FILE_URL 属性で指定のフォルダの下に、
410         * さらに、各個人ID別のフォルダを作成して、そこに出力します。
411         *
412         * @og.rev 4.0.0.0 (2007/11/20) 指定されたディレクトリ名の最後が"\"or"/"で終わっていない場合に、"/"を付加する。
413         *
414         * @param       url 出力HTMLファイルのディレクトリ
415         */
416        public void setOutFileURL( final String url ) {
417                String furl = nval( getRequestParameter( url ),null );
418                if( furl != null ) {
419                        char ch = furl.charAt( furl.length()-1 );
420                        if( ch != '/' && ch != '\\' ) { furl = furl + "/"; }
421                        outFileURL = StringUtil.urlAppend( outFileURL,furl );
422                }
423        }
424
425        /**
426         * 【TAG】ファイルを作成するときの出力ファイル名をセットします。
427         *
428         * @og.tag ファイルを作成するときの出力ファイル名をセットします。
429         *
430         * @param   filename 出力ファイル名
431         */
432        public void setOutFilename( final String filename ) {
433                this.outFilename = nval( getRequestParameter( filename ),this.outFilename );
434        }
435
436        /**
437         * 【TAG】実際に書き出すクラス名の略称(DBTableReport_**** の ****)をセットします(初期値:HTML)。
438         *
439         * @og.tag
440         * これは、org.opengion.hayabusa.report 以下の DBTableReport_**** クラスの **** を
441         * 与えます。これらは、DBTableReport インターフェースを継承したサブクラスです。
442         * 初期値は、"HTML" です。
443         * 属性クラス定義の {@link org.opengion.hayabusa.report.DBTableReport DBTableReport} を参照願います。
444         *
445         * @param   reportClass クラス名(の略称)
446         * @see         org.opengion.hayabusa.report.DBTableReport  DBTableReportのサブクラス
447         */
448        public void setReportClass( final String reportClass ) {
449                this.reportClass = nval( getRequestParameter( reportClass ),this.reportClass );
450        }
451
452        /**
453         * シェルコマンドの文字列を作成します。
454         *
455         * 処理クラス(reportClass)が HTML の場合は、Shell を起動して、VBS で EXCEL化が必要。
456         *
457         * @og.rev 3.8.0.4 (2005/08/08) 新規追加
458         * @og.rev 3.8.0.8 (2005/10/03) デーモングループのデフォルト値設定
459         *
460         * @param       htmlFile        パーサ済みのHTMLファイル(拡張子なし)
461         * @param       listId  雛形ファイル(帳票ID)
462         *
463         * @return シェルコマンドの文字列
464         */
465        private String makeShellCommand( final String htmlFile,final String listId ) {
466                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_SMALL );
467
468                buf.append( programFile ).append( " " );                // 実行するコマンド
469                buf.append( "\"" );
470                buf.append( htmlFile ).append( "_*.html\" " );  // 入力HTMLファイル
471                buf.append( "\"xls\" " );                                               // プリンタ名
472                // ダミーファイルを指定する必要がある。
473                buf.append( "\"" );
474                buf.append( htmlFile ).append( ".xls\" " );             // ダミー出力ファイル
475                buf.append( listId );                                                   // モデルファイル名
476                buf.append( " NULL" );                                                  // ダミーデーモングループ
477
478                return buf.toString();
479        }
480
481        /**
482         * 実際のレポート出力処理を行います。
483         *
484         * 処理クラス(reportClass)が HTML の場合は、Shell を起動して、VBS で EXCEL化が必要。
485         *
486         * @og.rev 3.8.0.4 (2005/08/08) 新規追加
487         *
488         * @param       shellCmd        シェルを実行するコマンド文字列
489         */
490        private void programRun( final String shellCmd ) {
491                Shell shell = new Shell();
492                shell.setCommand( shellCmd,true );              // BATCHプロセスで実行する
493                shell.setWait( true );                                  // プロセスの終了を待つ
494                shell.setTimeout( TIMEOUT );                    // 3.6.1.0 (2005/01/05) Shell の タイムアウトを設定
495
496                int rtnCode = shell.exec();                             // 0 は正常終了を示す
497
498                if( rtnCode != 0 ) {
499                        String errMsg = "Shell Command exequte Error." + HybsSystem.CR
500                                                + "=============================="
501                                                + shellCmd + HybsSystem.CR
502                                                + shell.getStdoutData() + HybsSystem.CR
503                                                + shell.getStderrData() + HybsSystem.CR ;
504                        throw new HybsSystemException( errMsg );                // 3.5.5.4 (2004/04/15) 引数の並び順変更
505                }
506        }
507
508        /**
509         * タグの名称を、返します。
510         * 自分自身のクラス名より、自動的に取り出せないため、このメソッドをオーバーライドします。
511         *
512         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
513         *
514         * @return  タグの名称
515         */
516        @Override
517        protected String getTagName() {
518                return "report" ;
519        }
520
521        /**
522         * シリアライズ用のカスタムシリアライズ書き込みメソッド
523         *
524         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
525         * @serialData 一部のオブジェクトは、シリアライズされません。
526         *
527         * @param       strm    ObjectOutputStreamオブジェクト
528         * @throws IOException  入出力エラーが発生した場合
529         */
530        private void writeObject( final ObjectOutputStream strm ) throws IOException {
531                strm.defaultWriteObject();
532        }
533
534        /**
535         * シリアライズ用のカスタムシリアライズ読み込みメソッド
536         *
537         * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。
538         *
539         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
540         * @serialData 一部のオブジェクトは、シリアライズされません。
541         *
542         * @param       strm    ObjectInputStreamオブジェクト
543         * @see #release2()
544         * @throws IOException  シリアライズに関する入出力エラーが発生した場合
545         * @throws ClassNotFoundException       クラスを見つけることができなかった場合
546         */
547        private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
548                strm.defaultReadObject();
549        }
550
551        /**
552         * このオブジェクトの文字列表現を返します。
553         * 基本的にデバッグ目的に使用します。
554         *
555         * @return このクラスの文字列表現
556         */
557        @Override
558        public String toString() {
559                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
560                                .println( "VERSION"             ,VERSION        )
561                                .println( "headerKeys"          ,headerKeys             )
562                                .println( "headerVals"          ,headerVals             )
563                                .println( "footerKeys"          ,footerKeys             )
564                                .println( "footerVals"          ,footerVals             )
565                                .println( "pageEndCut"          ,pageEndCut             )
566                                .println( "fileURL"                     ,fileURL                )
567                                .println( "outFileURL"          ,outFileURL             )
568                                .println( "outFilename"         ,outFilename    )
569                                .println( "reportClass"         ,reportClass    )
570                                .println( "tableId"                     ,tableId                )
571                                .println( "listId"                      ,listId                 )
572                                .println( "programFile"         ,programFile    )
573                                .println( "REPORT_FILE_URL"     ,REPORT_URL             )
574                                .println( "SYSTEM_ID"           ,SYSTEM_ID              )
575                                .println( "TIMEOUT"                     ,TIMEOUT                )
576                                .println( "BASE_URL"            ,BASE_URL               )
577                                .println( "Other..."    ,getAttributes().getAttribute() )
578                                .fixForm().toString() ;
579        }
580}