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; 028import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE ; 029 030/** 031 * ユニリタ「Report & Form Warehouse」に対応したCSV形式でデータを作成します。 032 * 033 * CSVPrintPointService_RFWとの違いは出力ファイル名のみです。 034 * CSVはシステムリソースRFW_CSV_OUTPUTDIRで指定した場所に[GRPID]_[YKNO]_[LISTID].csvで出力されます。 035 * 036 * @og.group 帳票システム 037 * 038 * @og.rev 5.9.27.1 (2017/12/08) 新規作成 039 * 040 * @version 5.9.0.0 041 * @author Masakazu Takahashi 042 * @since JDK6.0, 043 */ 044public class CSVPrintPointService_RFW2 extends AbstractCSVPrintPointService { 045 046 private static final String CR = System.getProperty("line.separator"); 047 private final StringBuilder strCSV = new StringBuilder( BUFFER_MIDDLE ); // CSVはこれに吐く 048 049 // 6.8.5.0 (2018/01/09) PMD Variables that are final and static should be all capitals。csvEncode → CSV_ENCODE 050 private static final String CSV_ENCODE = HybsSystem.sys("REPORT_CSV_TEXT_ENCODE"); 051 052 private static final String RFW_CSV_OUTPUTDIR = HybsSystem.sys("RFW_CSV_OUTPUTDIR"); 053 054 private static final String RFW_EXCEL_TYPE = StringUtil.nval( HybsSystem.sys("RFW_EXCEL_TYPE"), "XLS" ) ; 055 056 /** 057 * 発行処理。 058 * 059 * ファイル出力 060 * 061 * @og.rev 6.8.5.0 (2018/01/09) PMD Variables that are final and static should be all capitals。csvEncode → CSV_ENCODE 062 * 063 * @return 結果 [true:正常/false:異常] 064 */ 065 @Override 066 public boolean execute(){ 067 System.out.print( "CSV create ... " ); 068 BufferedWriter bw = null; 069 boolean flg = false; 070 071 try { 072 // outdirが\\から開始される場合に、次の\もしくは/までの文字列を出力フォルダに付け足す 073 // かつ、outdirからはサーバ名は削除する 074 String nasName = ""; 075 if( outdir != null && outdir.startsWith( "\\\\" ) ){ 076 int spl = outdir.indexOf( "\\", 2 ); 077 int spl2 = outdir.indexOf( "/", 2 ); 078 spl = spl<0 ? outdir.length() : spl; 079 spl2 = spl2<0 ? outdir.length() : spl2; 080 spl = spl < spl2 ? spl : spl2; 081 nasName = "_" + outdir.substring( 2, spl ); 082 outdir = outdir.substring(spl+1); 083 } 084 085 makeheader(); 086 makebody(); 087 088 // 汎用化も考えたが、予期せぬ出力があると困るのでBIG決め打ち。フォルダ存在しない場合はエラー 089 final String fnm = File.separator + grpid + "_" + ykno + "_" + listid + ".csv"; // 6.8.5.0 (2018/01/09) 090 if( dmngrp != null && dmngrp.indexOf( "BIG" ) >= 0 ){ 091 bw = getWriter( RFW_CSV_OUTPUTDIR + nasName + "_BIG" + fnm ,false,CSV_ENCODE); 092 } 093 else{ 094 bw = getWriter( RFW_CSV_OUTPUTDIR + nasName + fnm ,false,CSV_ENCODE); 095 } 096 bw.write( strCSV.toString() ); 097 bw.flush(); 098 bw.close(); 099 100 flg = true; 101 102 // 先頭が*のデーモングループの場合は約7秒スリープさせる=このスレッドでの連続処理をわざと遅延させる 103 // 特殊対応なので決め打ち 104 if( dmngrp != null && dmngrp.indexOf( "*" ) == 0 ){ 105 Thread.sleep(7000); 106 } 107 } 108 catch ( Throwable ex ) { 109 errMsg.append( "CSV Print Request Execution Error. " ).append( CR ); 110 errMsg.append( "==============================" ).append( CR ); 111 errMsg.append( "SYSTEM_ID=[" ).append( systemId ).append( "] , " ); 112 errMsg.append( "YKNO=[" ).append( ykno ).append( "] , " ); 113 errMsg.append( ex.toString() ); 114 errMsg.append( CR ); 115 throw new RuntimeException( errMsg.toString(), ex ); 116 } 117 return flg; 118 } 119 120 /** 121 * ヘッダの出力。 122 * 123 */ 124 private void makeheader(){ 125 //ヘッダデータを出力する場合はここで指定する。 126 strCSV.append( "<rdstart>" ).append( CR ) 127 .append( "RDSetForm=\"" ).append( modelname ).append( '"' ).append( CR ) 128 .append( "RDSetUserName=\"" ).append( systemId ).append( '"' ).append( CR ) //5.9.3.1 (2015/12/16) 129 .append( "RDSetComputer=\"" ).append( listid ).append( '_' ).append( grpid ).append( '_' ).append( ykno ).append( '"' ).append( CR ) 130 .append( "RDSetDocName=\"" ).append( listid ).append( '"' ).append( CR ); 131 132 String suffix = ""; // 5.9.6.0 133 134 // 5.9.6.0 拡張子を自動で付ける対応を入れておく 135 // PDFの場合 136 if( FGRUN_PDF.equals( fgrun ) ){ 137 if( outdir != null && outdir.indexOf( '.' ) < 0 ){ 138 suffix = ".pdf"; 139 } 140 141 strCSV.append( "RDSetOutputMode=PDF" ).append( CR ) 142 .append( "RDSetOutputFileName=\"" ).append( outdir ).append( suffix ).append( '"' ).append( CR ); 143 } 144 // Excel(XLS) 145 else if( FGRUN_EXCEL.equals(fgrun) ){ 146 if( outdir != null && outdir.indexOf( '.' ) < 0 ){ 147 suffix = ".xls"; 148 } 149 strCSV.append( "RDSetOutputMode=" + RFW_EXCEL_TYPE ).append( CR ) 150 .append( "RDSetOutputFileName=\"" ).append( outdir ).append( suffix ).append( '"' ).append( CR ); 151 } 152 else if( FGRUN_EXCEL2.equals(fgrun) ){ 153 if( outdir != null && outdir.indexOf( '.' ) < 0 ){ 154 suffix = ".xlsx"; 155 } 156 strCSV.append( "RDSetOutputMode=XLSX" ).append( CR ) 157 .append( "RDSetOutputFileName=\"" ).append( outdir ).append( suffix ).append( '"' ).append( CR ); 158 } 159 // 印刷 160 else{ 161 strCSV.append( "RDSetOutputMode=SPOOL" ).append( CR ) 162 .append( "RDSetOutputPrinter=\"" ).append(prtid).append( '"' ).append( CR ); 163 } 164 165 if( option != null && option.length() > 0 ){ 166 strCSV.append( option ).append( CR ); // 5.9.3.0 (2015/12/04) 167 } 168 169 strCSV.append( "<rdend>" ).append( CR ); 170 171 //1行目にカラム名を出力します。クウォートで囲わない。 172 // メインテーブルはNULLではない 173 for( int clmNo=0; clmNo<table.getColumnCount(); clmNo++ ) { 174 // 先頭以外はカンマを付ける 175 if( clmNo > 0 ){ strCSV.append( ',' ); } 176 strCSV.append( table.getColumnName( clmNo )); 177 } 178 if( tableH != null){ 179 for( int clmNo=0; clmNo<tableH.getColumnCount(); clmNo++ ) { 180 strCSV.append( ",H_" ).append( tableH.getColumnName( clmNo ) ); 181 } 182 } 183 if( tableF != null){ 184 for( int clmNo=0; clmNo<tableF.getColumnCount(); clmNo++ ) { 185 strCSV.append( ",F_" ).append( tableF.getColumnName( clmNo ) ); 186 } 187 } 188 strCSV.append( CR ); 189 } 190 191 /** 192 * 本体の出力を行います。 193 * HTMLエスケープされている場合は戻します 194 */ 195 private void makebody(){ 196 197 for( int rowNo=0; rowNo<table.getRowCount(); rowNo++ ) { 198 // カラム単位の処理 199 for( int clmNo=0; clmNo<table.getColumnCount(); clmNo++ ) { 200 // 先頭以外はカンマを付ける 201 if( clmNo > 0 ){ strCSV.append( "," ); } 202 // 原則全てダブルクウォートで囲う 203 // 5.9.8.2 (2016/05/16) 但し、先頭カラムが制御コードである//EOR//の場合のみ囲わない 204 if( clmNo == 0 && "//EOR//".equals( table.getValue( rowNo, clmNo )) ){ 205 strCSV.append( table.getValue( rowNo, clmNo ) ); 206 } 207 else{ 208 strCSV.append( '"' ) 209 .append( StringUtil.replace( StringUtil.getReplaceEscape( table.getValue( rowNo, clmNo )) ,"\"","\"\"" ) ) 210 .append( '"' ); 211 } 212 } 213 214 //ヘッダ、フッタは毎行に必ず付加します。 215 //例え複数行あったとしても先頭行のみ有効です 216 //ヘッダ 217 if( tableH != null){ 218 int rowNoH=0; 219 for( int clmNo=0; clmNo<tableH.getColumnCount(); clmNo++ ) { 220 // 必ずカンマを付ける 221 strCSV.append( ",\"" ) // 全てダブルクウォートで囲う 222 .append( StringUtil.replace( StringUtil.getReplaceEscape( tableH.getValue( rowNoH, clmNo )) ,"\"","\"\"" ) ) 223 .append( '"' ); 224 } 225 } 226 227 //フッタ 228 if( tableF != null ){ 229 int rowNoF=0; 230 for( int clmNo=0; clmNo<tableF.getColumnCount(); clmNo++ ) { 231 // 必ずカンマを付ける 232 strCSV.append( ",\"" ) // 全てダブルクウォートで囲う 233 .append( StringUtil.replace( StringUtil.getReplaceEscape( tableF.getValue( rowNoF, clmNo )) ,"\"","\"\"" ) ) 234 .append( '"' ); 235 } 236 } 237 strCSV.append( CR ); 238 } 239 } 240 241 /** 242 * ファイル書き込み用のライターを返します。 243 * 244 * @param fileName ファイル名 245 * @param append アベンドするか 246 * @param encode エンコード 247 * 248 * @return ライター 249 */ 250 private BufferedWriter getWriter( final String fileName, final boolean append, final String encode) { 251 final File file = new File ( fileName ); 252 BufferedWriter bw; 253 254 try { 255 bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( file, append ), encode ) ); 256 } 257 catch ( UnsupportedEncodingException ex ) { 258 errMsg.append( "[ERROR] Input File is written by Unsupported Encoding" ); 259 throw new HybsSystemException( ex ); 260 } 261 catch ( FileNotFoundException ex ) { 262 errMsg.append( "[ERROR] File not Found" ); 263 throw new HybsSystemException( ex ); 264 } 265 return bw; 266 } 267}