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         * @og.rev 5.9.1.2 (2015/10/23) RDSetOutputPrinterの値をIDに変更
102         */
103        private void makeheader(){
104                //ヘッダデータを出力する場合はここで指定する。
105                strCSV.append( "<rdstart>" ).append( CR );
106                
107                strCSV.append( "RDSetForm=\"" ).append(modelname).append("\"").append( CR );
108
109                // PDFの場合
110                if( FGRUN_PDF.equals( fgrun ) ){
111                        strCSV.append( "RDSetOutputMode=PDF" ).append( CR );
112                        strCSV.append( "RDSetOutputFileName=\"" ).append( outdir ).append("\"").append( CR );
113                }
114                // Excel
115                else if( FGRUN_EXCEL.equals(fgrun) ){
116                        strCSV.append( "RDSetOutputMode=XLS" ).append( CR );
117                        strCSV.append( "RDSetOutputFileName=\"" ).append( outdir ).append("\"").append( CR );
118                }
119                // 印刷
120                else{
121                        strCSV.append( "RDSetOutputMode=SPOOL" ).append( CR );
122                        //strCSV.append( "RDSetOutputPrinter=\"" ).append(prtName).append( "\"" ).append( CR );
123                        // プリンタ名ではなく、プリンタIDを出力するように変更
124                        strCSV.append( "RDSetOutputPrinter=\"" ).append(prtid).append( "\"" ).append( CR );
125                }
126                
127                strCSV.append( "<rdend>" ).append( CR );
128                
129                //1行目にカラム名を出力します。クウォートで囲わない。
130                // メインテーブルはNULLではない
131                for( int clmNo=0; clmNo<table.getColumnCount(); clmNo++ ) {
132                        // 先頭以外はカンマを付ける
133                        if( clmNo > 0 ){ strCSV.append( "," ); } 
134                        strCSV.append( table.getColumnName( clmNo ));
135                }
136                if( tableH != null){
137                        for( int clmNo=0; clmNo<tableH.getColumnCount(); clmNo++ ) {
138                                strCSV.append( "," ); 
139                                strCSV.append("H_").append( tableH.getColumnName( clmNo ));
140                        }
141                }
142                if( tableF != null){
143                        for( int clmNo=0; clmNo<tableF.getColumnCount(); clmNo++ ) {
144                                strCSV.append( "," ); 
145                                strCSV.append("F_").append( tableF.getColumnName( clmNo ));
146                        }
147                }
148                strCSV.append( CR );
149        }
150
151
152
153        /**
154         * 本体の出力を行います
155         * HTMLエスケープされている場合は戻します
156         */
157        private void makebody(){
158
159                for( int rowNo=0; rowNo<table.getRowCount(); rowNo++ ) {
160                        // カラム単位の処理
161                        for( int clmNo=0; clmNo<table.getColumnCount(); clmNo++ ) {
162                                // 先頭以外はカンマを付ける
163                                if( clmNo > 0 ){ strCSV.append( "," ); } 
164                                // 全てダブルクウォートで囲う
165                                strCSV.append("\"").append( StringUtil.replace( StringUtil.getReplaceEscape( table.getValue( rowNo, clmNo )) ,"\"","\"\"" ) ).append("\"");
166                        }
167                        
168                        //ヘッダ、フッタは毎行に必ず付加します。
169                        //例え複数行あったとしても先頭行のみ有効です
170                        //ヘッダ
171                        if( tableH != null){
172                                int rowNoH=0;
173                                for( int clmNo=0; clmNo<tableH.getColumnCount(); clmNo++ ) {
174                                        // 必ずカンマを付ける
175                                        strCSV.append( "," ); 
176                                        // 全てダブルクウォートで囲う
177                                        strCSV.append("\"").append( StringUtil.replace( StringUtil.getReplaceEscape( tableH.getValue( rowNoH, clmNo )) ,"\"","\"\"" ) ).append("\"");
178                                }
179                        }
180                        
181                        //フッタ
182                        if( tableF != null ){
183                                int rowNoF=0;
184                                for( int clmNo=0; clmNo<tableF.getColumnCount(); clmNo++ ) {
185                                        // 必ずカンマを付ける
186                                        strCSV.append( "," ); 
187                                        // 全てダブルクウォートで囲う
188                                        strCSV.append("\"").append( StringUtil.replace( StringUtil.getReplaceEscape( table.getValue( rowNoF, clmNo )) ,"\"","\"\"" ) ).append("\"");
189                                }
190                        }
191
192                        strCSV.append( CR );
193                }
194        }
195
196
197        /**
198         * ファイル書き込み用のライターを返します。
199         *
200         * @param fileName ファイル名
201         * @param append アベンドするか
202         * @param encode エンコード
203         *
204         * @return ライター
205         */
206        private BufferedWriter getWriter( final String fileName, final boolean append, final String encode) {
207                File file = new File ( fileName );
208                BufferedWriter bw;
209
210                try {
211                        bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( file, append ), encode ) );
212                }
213                catch ( UnsupportedEncodingException ex ) {
214                        errMsg.append( "[ERROR] Input File is written by Unsupported Encoding" );
215                        throw new HybsSystemException( ex );
216                }
217                catch ( FileNotFoundException ex ) {
218                        errMsg.append( "[ERROR] File not Found" );
219                        throw new HybsSystemException( ex );
220                }
221                return bw;
222        }
223
224}