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