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