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.report; 017 018import org.opengion.hayabusa.common.HybsSystem; 019import org.opengion.hayabusa.db.DBTableModelUtil; 020import org.opengion.hayabusa.db.DBTableModel; 021import org.opengion.hayabusa.resource.ResourceFactory; 022import org.opengion.hayabusa.resource.ResourceManager; 023 024import org.opengion.fukurou.util.StringUtil; 025import org.opengion.fukurou.system.ThrowUtil; 026import org.opengion.fukurou.util.FileUtil; 027import org.opengion.fukurou.db.ApplicationInfo; 028import org.opengion.fukurou.db.DBUtil; 029import static org.opengion.fukurou.system.HybsConst.CR ; // 6.1.0.0 (2014/12/26) 030import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE; // 6.1.0.0 (2014/12/26) refactoring 031 032import java.io.File; 033 034/** 035 * 【レポート出力】DBTableModelオブジェクトをレポート形式に返還するタグリブクラスです。 036 * このオブジェクトに、 データ(DBTableModel)と、コントローラ(DBTableReport クラス)を与えて、 037 * 外部からコントロールすることで、各種形式で データ(DBTableModel)を表示させることが 038 * 可能です。 039 * 040 * @og.group 帳票システム 041 * 042 * @version 4.0 043 * @author Kazuhiko Hasegawa 044 * @since JDK5.0, 045 */ 046public class ReportConverter { 047 private final StringBuilder errMsg ; 048 049 // DBTableReport に対して設定する情報 050 private String[] headerKeys ; // 固定部の key 部分を指定する。カンマで複数指定できる。 051 private String[] headerVals ; // 固定部の key に対応する値を指定する。 052 private String[] footerKeys ; // 繰り返し部の終了後に表示する key 部分を指定する。カンマで複数指定できる。 053 private String[] footerVals ; // 繰り返し部の終了後に表示する key に対する値を指定する。 054 private boolean pageEndCut ; // ボディー部(繰り返し部)がなくなったときに、それ以降のページを出力するか指定する。 055 private File templateFile ; // 3.8.0.0 (2005/06/07) 056 private File firstTemplateFile; // 3.8.0.0 (2005/06/07) 057 private DBTableModel table ; 058 private ResourceManager resource ; // 4.0.0 (2005/01/31) 059 060 // 受け渡し変数 061 private final String SYSTEM_ID ; 062 private final String YKNO ; 063 private final String LISTID ; 064 private final String HTML_DIR ; 065 private final String LANG ; 066 private final boolean DEBUG ; // 3.8.5.0 (2006/03/06) デバッグ用のフラグを追加 067 068 // GE54 帳票定義マスタ 069 private String modelDIR ; 070 private String modelFILE ; 071 private String hSQL ; 072 private String fSQL ; 073 private String bSQL ; 074 private boolean fgLOCAL ; // 0:未使用 1:使用 4.0.0 (2005/01/31) 075 private boolean fgDIRECT ; // 0:未使用 1:使用 4.0.0 (2005/01/31) 076 077 // GE54 の帳票定義情報を取得するSQL文です。 078 // 4.0.0 (2005/01/31) 共有 system_id を、考慮 079 private static final String GE54_SELECT = 080 "SELECT MODELDIR,MODELFILE,FGCUT,HSQL,FSQL,BSQL,FGLOCAL,FGDIRECT,SYSTEM_ID" + // 4.0.0 (2005/01/31) 081 " FROM GE54" + 082 " WHERE FGJ = '1'" + 083 " AND SYSTEM_ID IN (?,'**')" + 084 " AND LISTID = ?" ; 085 086 private static final int GE54_MODELDIR = 0; 087 private static final int GE54_MODELFILE = 1; 088 private static final int GE54_FGCUT = 2; 089 private static final int GE54_HSQL = 3; 090 private static final int GE54_FSQL = 4; 091 private static final int GE54_BSQL = 5; 092 private static final int GE54_FGLOCAL = 6; 093 private static final int GE54_FGDIRECT = 7; 094 private static final int GE54_SYSTEM_ID = 8; 095 096 /** コネクションにアプリケーション情報を追記するかどうか指定 */ 097 public static final boolean USE_DB_APPLICATION_INFO = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ; 098 099 // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 100 private final ApplicationInfo appInfo; 101 private final String DBID = HybsSystem.sys( "RESOURCE_DBID" ); // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対応 102 103 /** 104 * コンストラクター 105 * 引数を受けとって、インスタンスを作成します。 106 * 107 * @og.rev 3.0.0.4 (2003/02/26) FGRUN が PRT のみのときは,MODELFILE のみセットして終了する。 108 * @og.rev 3.8.0.0 (2005/06/07) FGRUNは,使用しない 109 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 110 * 111 * @param system_id システムID 112 * @param ykno 要求番号 113 * @param listId 帳票ID 114 * @param tempDir 出力ディレクトリ 115 * @param lang 言語 116 * @param debug デバッグフラグ言語 117 */ 118 public ReportConverter( final String system_id, final String ykno, final String listId, 119 final String tempDir,final String lang,final boolean debug ) { 120 SYSTEM_ID = system_id; 121 YKNO = ykno; 122 LISTID = listId; 123 HTML_DIR = tempDir; 124 LANG = lang; 125 DEBUG = debug; 126 errMsg = new StringBuilder( BUFFER_MIDDLE ); 127 128 // 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 129 if( USE_DB_APPLICATION_INFO ) { 130 appInfo = new ApplicationInfo(); 131 // ユーザーID,IPアドレス,ホスト名 132 appInfo.setClientInfo( SYSTEM_ID,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME ); 133 // 画面ID,操作,プログラムID 134 appInfo.setModuleInfo( "ReportConverter",YKNO,LISTID ); 135 } 136 else { 137 appInfo = null; 138 } 139 } 140 141 /** 142 * 変換処理を実行します。 143 * 144 * @og.rev 3.0.0.4 (2003/02/26) FGRUN が PRT のみのときは,MODELFILE のみセットして終了する。 145 * @og.rev 3.5.4.9 (2004/02/25) 存在チェックエラー(原因不明)の暫定対応 146 * @og.rev 3.8.0.0 (2005/06/07) initialDataSet() を ReportProcessing 側で呼び出します。 147 * @og.rev 6.4.2.0 (2016/01/29) StringUtil#stringStackTrace(Throwable) を、ThrowUtil#ogStackTrace(Throwable) に置き換え。 148 * 149 * @return 結果 [true:正常/false:異常] 150 */ 151 public boolean execute() { 152 System.out.print( "ReportConverter Started ... " ); 153 boolean flag = true; 154 155 try { 156 // 雛形ファイルのチェック 157 // 3.8.0.0 (2005/06/07) 存在チェックは、FileUtil.checkFile で行う。 158 if( flag ) { 159 System.out.print( "MDL CK," ); 160 templateFile = FileUtil.checkFile( modelDIR, modelFILE + ".html" ); 161 flag = templateFile != null ; // チェックの結果が null なら、見つからなかった。 162 163 if( !flag ) { 164 errMsg.append( "ModelFile Not Found Error !" ).append( CR ) 165 .append( "MODELDIR=" ).append( modelDIR ).append( CR ) 166 .append( "MODELFILE=" ).append( modelFILE ).append( ".html" ).append( CR ); // 6.0.2.5 (2014/10/31) char を append する。 167 } 168 } 169 170 // ファーストページ雛形ファイルのチェック(なくても良い) 171 // 3.8.0.0 (2005/06/07) 存在チェックは、FileUtil.checkFile で行う。 172 if( flag ) { 173 // チェックは、1回のみ行う。 174 firstTemplateFile = FileUtil.checkFile( modelDIR, modelFILE + "_FIRST.html",1 ); 175 } 176 177 // ヘッダ,フッタ, ボディー部の SQL を実行します。 178 if( flag ) { 179 flag = isHeaderFooter(); 180 if( flag ) { System.out.print( "HF SQL," ); } 181 } 182 183 // 帳票変換処理を実行します。 184 if( flag ) { 185 flag = reportRun(); 186 if( flag ) { System.out.print( "RPT RUN," ); } 187 } 188 } 189 catch( final RuntimeException ex ) { 190 errMsg.append( "ReportConverter Execute Exception Error!" ).append( CR ) 191 .append( "==============================" ).append( CR ) 192 .append( ThrowUtil.ogStackTrace( ex ) ).append( CR ) ; // 6.4.2.0 (2016/01/29) 193 flag = false; 194 } 195 196 System.out.println( "End." ); 197 return flag ; 198 } 199 200 /** 201 * 初期データセットを行います。 202 * ここでは、GE54 テーブルより必要な情報を取得します。 203 * 204 * @og.rev 3.8.0.0 (2005/06/07) initialDataSet() を ReportProcessing 側で呼び出します。 205 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 206 * @og.rev 4.0.0.0 (2005/01/31) ローカルリソースフラグとダイレクトアクセスフラグを追加 207 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策 208 * 209 * @return 結果 [true:正常/false:異常] 210 */ 211 public boolean initialDataSet() { 212 final String[] args = new String[] { SYSTEM_ID,LISTID }; 213 // modeldir,modelfile,fgcut,hsql,fsql,bsql,fglocal,fgdirect,system_id 214 final String[][] vals = DBUtil.dbExecute( GE54_SELECT,args,appInfo, DBID ); // 5.5.5.1 (2012/08/07) 215 if( vals == null || vals.length == 0 ) { 216 errMsg.append( "Data does not exist in GE54 table." ).append( CR ) 217 .append( "==============================" ).append( CR ) 218 .append( "SYSTEM_ID=[" ).append( SYSTEM_ID ) 219 .append( "] , LISTID=[" ).append( LISTID ).append( ']' ) // 6.0.2.5 (2014/10/31) char を append する。 220 .append( CR ); 221 return false; 222 } 223 224 int row = 0; 225 // 検索結果が複数帰ったとき、SYSTEM_ID が 指定されている方のデータ(行)を採用する。 226 for( int i=0; i<vals.length; i++ ) { 227 if( SYSTEM_ID.equalsIgnoreCase( vals[i][GE54_SYSTEM_ID] ) ) { row = i; break; } 228 } 229 230 modelDIR = StringUtil.nval( vals[row][GE54_MODELDIR],modelDIR ); 231 modelFILE = StringUtil.nval( vals[row][GE54_MODELFILE],modelFILE ); 232 pageEndCut = StringUtil.nval( vals[row][GE54_FGCUT],pageEndCut ); // boolean タイプ 233 234 if( DEBUG ) { 235 System.out.println( "MODELDIR = [" + modelDIR + "]" ); 236 System.out.println( "MODELFILE = [" + modelFILE + "]" ); 237 System.out.println( "pageEndCut = [" + pageEndCut + "]" ); 238 } 239 240 hSQL = StringUtil.nval( vals[row][GE54_HSQL],hSQL ); 241 fSQL = StringUtil.nval( vals[row][GE54_FSQL],fSQL ); 242 bSQL = StringUtil.nval( vals[row][GE54_BSQL],bSQL ); 243 if( bSQL == null || bSQL.isEmpty() ) { 244 errMsg.append( "Body SQL Columns does not exist in GE54 table." ).append( CR ) 245 .append( "==============================" ).append( CR ) 246 .append( "SYSTEM_ID=[" ).append( SYSTEM_ID ) 247 .append( "] , LISTID=[" ).append( LISTID ).append( "] " ) 248 .append( CR ); 249 return false; 250 } 251 252 // 4.0.0 (2005/01/31) ローカルリソースフラグとダイレクトアクセスフラグを追加 253 fgLOCAL = vals[row][GE54_FGLOCAL] != null && vals[row][GE54_FGLOCAL].trim().equals( "1" ) ; 254 fgDIRECT= vals[row][GE54_FGDIRECT] != null && vals[row][GE54_FGDIRECT].trim().equals( "1" ) ; 255 256 return true; 257 } 258 259 /** 260 * ヘッダーフッター情報の取得を行います。 261 * GE54 の HSQL,FSQL,BSQL のコマンドを実行して、データを取得します。 262 * ヘッダー情報、フッター情報がなくても異常とは判断されませんが、 263 * ボディ情報が存在しない場合は、エラーとなります。 264 * 265 * @og.rev 3.0.0.1 (2003/02/14) ヘッダー、フッター情報が null のときの処理追加。 266 * @og.rev 3.0.1.3 (2003/03/11) 検索時の最大件数での打ち切りをエラーとする。 267 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定 268 * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更 , メソッド名変更 269 * 270 * @return 結果 [true:正常/false:異常] 271 */ 272 private boolean isHeaderFooter() { 273 // 4.0.0 (2005/01/31) FGLOCAL 指定時は、SYSTEM_ID を指定してリソース作成 274 if( fgLOCAL ) { 275 // ローカルリソース指定時は、SYSTEM_ID,LANG を使用します。先読みは、使用しません。 276 resource = ResourceFactory.newInstance( SYSTEM_ID,LANG,false ); // 4.0.0 (2005/01/31) 277 } 278 else { 279 // 従来と互換性のあるモード(ローカルリソースは使用しない。 280 resource = ResourceFactory.newInstance( LANG ); // 4.0.0 (2005/01/31) 281 } 282 283 // 4.0.0 (2005/01/31) FGDIRECT 指定時は、where 条件は、null になります。 284 final String[] where = fgDIRECT ? null : new String[] { SYSTEM_ID , YKNO } ; 285 286 // ヘッダー情報の取得 287 final DBTableModel header = DBTableModelUtil.makeDBTable( hSQL, where, resource, appInfo ); // 3.8.7.0 (2006/12/15) 288 if( header != null && header.getRowCount() > 0 ) { 289 headerKeys = header.getNames(); 290 final Object[] obj = header.getValues(0); 291 headerVals = new String[obj.length]; 292 for( int i=0; i<obj.length; i++ ) { 293 headerVals[i] = obj[i].toString().trim(); 294 } 295 } 296 297 // フッター情報の取得 298 final DBTableModel footer = DBTableModelUtil.makeDBTable( fSQL, where, resource ,appInfo ); // 3.8.7.0 (2006/12/15) 299 if( footer != null && footer.getRowCount() > 0 ) { 300 footerKeys = footer.getNames(); 301 final Object[] obj = footer.getValues(0); 302 footerVals = new String[obj.length]; 303 for( int i=0; i<obj.length; i++ ) { 304 footerVals[i] = obj[i].toString().trim(); 305 } 306 } 307 308 // ボディー情報の取得 309 table = DBTableModelUtil.makeDBTable( bSQL, where, resource ,appInfo ); // 3.8.7.0 (2006/12/15) 310 if( table.getRowCount() <= 0 ) { 311 errMsg.append( "Database Body row count is Zero." ).append( CR ) 312 .append( "==============================" ).append( CR ) 313 .append( bSQL ) 314 .append( CR ); 315 return false; 316 } 317 // 3.0.1.3 (2003/03/11) 検索時の最大件数での打ち切りをエラーとする。 318 if( table.isOverflow() ) { 319 errMsg.append( "Database is Overflow. [" ) 320 .append( table.getRowCount() ) 321 .append( ']' ).append( CR ).append( CR ) // 6.0.2.5 (2014/10/31) char を append する。 322 .append( "==============================" ).append( CR ) 323 .append( "Check SystemParameter Data in DB_MAX_ROW_COUNT Overflow" ) 324 .append( CR ); 325 return false; 326 } 327 328 return true; 329 } 330 331 /** 332 * 実際のレポート変換処理を行います。 333 * 334 * @og.rev 3.5.4.3 (2004/01/05) HTMLDBTableReport のクラス名変更。 335 * @og.rev 3.6.0.0 (2004/09/17) メソッド名の変更。setInputFile ⇒ setTemplateFile 336 * @og.rev 3.6.1.0 (2005/01/05) 帳票ID(LISTID)をセットします。 337 * @og.rev 3.8.5.1 (2006/04/28) setOutputFileKey の代わりに、setYkno を使用します。 338 * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更 339 * 340 * @return 結果 [true:正常/false:異常] 341 */ 342 private boolean reportRun() { 343 final DBTableReport report = new DBTableReport_HTML(); 344 345 report.setDBTableModel( table ); 346 report.setTemplateFile( templateFile ); // 3.6.0.0 (2004/09/17) 347 report.setFirstTemplateFile( firstTemplateFile ); // 3.6.0.0 (2004/09/17) 348 report.setOutputDir( HTML_DIR ); 349 report.setOutputFileKey( YKNO ); // 要求番号をファイル名として使用します。 350 report.setYkno( YKNO ); // 3.8.5.1 (2006/04/28) 351 report.setHeaderKeys( headerKeys ); 352 report.setHeaderVals( headerVals ); 353 report.setFooterKeys( footerKeys ); 354 report.setFooterVals( footerVals ); 355 report.setPageEndCut( pageEndCut ); 356 report.setResourceManager( resource ); // 4.0.0 (2005/01/31) 357 report.setListId( LISTID ); // 3.6.1.0 (2005/01/05) 358 report.writeReport(); 359 360 return true; 361 } 362 363 /** 364 * modelFILE を返します。 365 * 366 * @og.rev 6.4.2.1 (2016/02/05) メソッド名変更 ReportConverter#modelFile() → ReportConverter#getModelFile() 。 367 * 368 * @return modelFILE名 369 */ 370 public String getModelFile() { 371 return modelFILE ; 372 } 373 374 /** 375 * エラーが存在した場合に、エラーメッセージを返します。 376 * 377 * @return エラーメッセージ String 378 * @og.rtnNotNull 379 */ 380 public String getErrMsg() { 381 return errMsg.toString(); 382 } 383}