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.plugin.report;
017
018import java.io.BufferedWriter;
019import java.io.File;
020import java.io.FileNotFoundException;
021import java.io.FileOutputStream;
022import java.io.OutputStreamWriter;
023import java.io.UnsupportedEncodingException;
024import org.opengion.hayabusa.common.HybsSystemException;
025import org.opengion.hayabusa.common.HybsSystem;
026import org.opengion.hayabusa.report.AbstractCSVPrintPointService;
027import org.opengion.fukurou.util.StringUtil;
028
029/**
030 * ユニリタ「Report & Form Warehouse」に対応したCSV形式でデータを作成します。
031 * 
032 * CSVはシステムリソースRFW_CSV_OUTPUTDIRで指定した場所に[LISTID]_[YKNO].csvで出力されます。
033 * PDF等の最終的な出力先、つまりCSVのコントロールヘッダのRDSetOutputFileNameはGE50で指定します。
034 * (Defaultのプラグインと出力が異なるので注意が必要です)
035 * 
036 * データに関しては、全てダブルクウォートで囲って出力されます。
037 * ダブルクウォートそのものは二重化でエスケープします。
038 * ヘッダ、フッタが存在する場合、ボディ、ヘッダ、フッタの順番に連結して出力し、カラム名はヘッダはH_、フッタはF_を先頭に追加します。
039 * 
040 *
041 * @og.group 帳票システム
042 *
043 * @version  5.9.0.0
044 * @author       Masakazu Takahashi
045 * @since    JDK6.0,
046 */
047public class CSVPrintPointService_RFW extends AbstractCSVPrintPointService {
048
049        private static final String CR          = System.getProperty("line.separator");
050        private final StringBuilder strCSV      = new StringBuilder();  // CSVはこれに吐く
051
052        private static final String     csvEncode       = HybsSystem.sys("REPORT_CSV_TEXT_ENCODE");
053        
054        private static final String RFW_CSV_OUTPUTDIR = HybsSystem.sys("RFW_CSV_OUTPUTDIR");
055
056        /**
057         * 発行処理
058         * ファイル出力
059         *
060         * @return 結果 [true:正常/false:異常]
061         */
062        @Override
063        public boolean execute(){
064                System.out.print( "CSV create ... " );
065                BufferedWriter bw = null;
066                boolean flg = false;
067
068                try {
069                        makeheader();
070                        makebody();
071
072                        bw = getWriter( RFW_CSV_OUTPUTDIR + File.separator + listid + "_" + ykno + ".csv" ,false,csvEncode);
073                        bw.write( strCSV.toString() );
074                        bw.flush();
075                        bw.close();
076
077                        flg = true;
078                        
079//                      if( prgfile != null && prgfile.length() > 0){
080//                              makeShellCommand();
081//                              flg = programRun();
082//                      }
083
084                }
085                catch ( Throwable ex ) {
086                        errMsg.append( "CSV Print Request Execution Error. " ).append( CR );
087                        errMsg.append( "==============================" ).append( CR );
088                        errMsg.append( "SYSTEM_ID=[" ).append( systemId ).append( "] , " );
089                        errMsg.append( "YKNO=["    ).append( ykno    ).append( "] , " );
090                        errMsg.append( ex.toString() );
091                        errMsg.append( CR );
092//                      throw new RuntimeException( errMsg.toString() );
093                        throw new RuntimeException( errMsg.toString(), ex );
094                }
095                return flg;
096        }
097
098        /**
099         * ヘッダの出力
100         *
101         */
102        private void makeheader(){
103                //ヘッダデータを出力する場合はここで指定する。
104                strCSV.append( "<rdstart>" ).append( CR );
105                
106                strCSV.append( "RDSetForm=\"" ).append(modelname).append("\"").append( CR );
107
108                // PDFの場合
109                if( FGRUN_PDF.equals( fgrun ) ){
110                        strCSV.append( "RDSetOutputMode=PDF" ).append( CR );
111                        strCSV.append( "RDSetOutputFileName=\"" ).append( outdir ).append("\"").append( CR );
112                }
113                // Excel
114                else if( FGRUN_EXCEL.equals(fgrun) ){
115                        strCSV.append( "RDSetOutputMode=XLS" ).append( CR );
116                        strCSV.append( "RDSetOutputFileName=\"" ).append( outdir ).append("\"").append( CR );
117                }
118                // 印刷
119                else{
120                        strCSV.append( "RDSetOutputMode=SPOOL" ).append( CR );
121                        strCSV.append( "RDSetOutputPrinter=\"" ).append(prtName).append( "\"" ).append( CR );
122                }
123                
124                strCSV.append( "<rdend>" ).append( CR );
125                
126                //1行目にカラム名を出力します。クウォートで囲わない。
127                // メインテーブルはNULLではない
128                for( int clmNo=0; clmNo<table.getColumnCount(); clmNo++ ) {
129                        // 先頭以外はカンマを付ける
130                        if( clmNo > 0 ){ strCSV.append( "," ); } 
131                        strCSV.append( table.getColumnName( clmNo ));
132                }
133                if( tableH != null){
134                        for( int clmNo=0; clmNo<tableH.getColumnCount(); clmNo++ ) {
135                                strCSV.append( "," ); 
136                                strCSV.append("H_").append( tableH.getColumnName( clmNo ));
137                        }
138                }
139                if( tableF != null){
140                        for( int clmNo=0; clmNo<tableF.getColumnCount(); clmNo++ ) {
141                                strCSV.append( "," ); 
142                                strCSV.append("F_").append( tableF.getColumnName( clmNo ));
143                        }
144                }
145                strCSV.append( CR );
146        }
147
148
149
150        /**
151         * 本体の出力を行います
152         * HTMLエスケープされている場合は戻します
153         */
154        private void makebody(){
155
156                for( int rowNo=0; rowNo<table.getRowCount(); rowNo++ ) {
157                        // カラム単位の処理
158                        for( int clmNo=0; clmNo<table.getColumnCount(); clmNo++ ) {
159                                // 先頭以外はカンマを付ける
160                                if( clmNo > 0 ){ strCSV.append( "," ); } 
161                                // 全てダブルクウォートで囲う
162                                strCSV.append("\"").append( StringUtil.replace( StringUtil.getReplaceEscape( table.getValue( rowNo, clmNo )) ,"\"","\"\"" ) ).append("\"");
163                        }
164                        
165                        //ヘッダ、フッタは毎行に必ず付加します。
166                        //例え複数行あったとしても先頭行のみ有効です
167                        //ヘッダ
168                        if( tableH != null){
169                                int rowNoH=0;
170                                for( int clmNo=0; clmNo<tableH.getColumnCount(); clmNo++ ) {
171                                        // 必ずカンマを付ける
172                                        strCSV.append( "," ); 
173                                        // 全てダブルクウォートで囲う
174                                        strCSV.append("\"").append( StringUtil.replace( StringUtil.getReplaceEscape( tableH.getValue( rowNoH, clmNo )) ,"\"","\"\"" ) ).append("\"");
175                                }
176                        }
177                        
178                        //フッタ
179                        if( tableF != null ){
180                                int rowNoF=0;
181                                for( int clmNo=0; clmNo<tableF.getColumnCount(); clmNo++ ) {
182                                        // 必ずカンマを付ける
183                                        strCSV.append( "," ); 
184                                        // 全てダブルクウォートで囲う
185                                        strCSV.append("\"").append( StringUtil.replace( StringUtil.getReplaceEscape( table.getValue( rowNoF, clmNo )) ,"\"","\"\"" ) ).append("\"");
186                                }
187                        }
188
189                        strCSV.append( CR );
190                }
191        }
192
193
194        /**
195         * ファイル書き込み用のライターを返します。
196         *
197         * @param fileName ファイル名
198         * @param append アベンドするか
199         * @param encode エンコード
200         *
201         * @return ライター
202         */
203        private BufferedWriter getWriter( final String fileName, final boolean append, final String encode) {
204                File file = new File ( fileName );
205                BufferedWriter bw;
206
207                try {
208                        bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( file, append ), encode ) );
209                }
210                catch ( UnsupportedEncodingException ex ) {
211                        errMsg.append( "[ERROR] Input File is written by Unsupported Encoding" );
212                        throw new HybsSystemException( ex );
213                }
214                catch ( FileNotFoundException ex ) {
215                        errMsg.append( "[ERROR] File not Found" );
216                        throw new HybsSystemException( ex );
217                }
218                return bw;
219        }
220
221}