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.table; 017 018import org.opengion.hayabusa.common.HybsSystemException; 019import org.opengion.hayabusa.db.AbstractTableFilter; 020import org.opengion.hayabusa.db.DBTableModel; 021import org.opengion.fukurou.util.StringUtil; 022import org.opengion.fukurou.util.ErrorMessage; 023import org.opengion.fukurou.util.ErrMsg; 024import org.opengion.hayabusa.db.DBColumn; 025import org.opengion.hayabusa.resource.ResourceFactory; 026import org.opengion.hayabusa.resource.ResourceManager; 027import static org.opengion.fukurou.system.HybsConst.CR; 028 029/** 030 * TableFilter_JUDG は、TableFilter インターフェースを継承した、DBTableModel 処理用の 031 * 実装クラスです。 032 * 033 * 必要なカラムから、判定結果(JUDG) と 判定理由(RIYU) を設定します。 034 * これは、GG10 の発生日(DY_HATU),登録キー(SET_KEY),設定グループ(SET_GRP),トークン(TOKEN) の 035 * レコードを処理して、判定結果を設定します。 036 * 037 * GG10 書き込むテーブル (必須カラム) 038 * 値データ(VAL) 値の設定(存在、上限、下限判定) 039 * 判定結果(JUDG) 0:未決 1:不要 2:任意 3:合格 4:保留 5:警告 6:必須 7:不合格 040 * 判定理由(RIYU) 上限、下限で判定した結果が入っている。titleに入れてポップアップさせる 041 * 042 * GG01 トークンマスタ (GG02がnullの時) 043 * データ型(DATA_TYPE) EDITORを決定 044 * 045 * GG02 雛形設定マスタ 046 * 登録方法(CDREC) 0:未決 1:不要 2:任意 4:保留 6:必須 047 * 異常下限(E_MIN) 異常値の下限判定に使用 048 * 警告下限(W_MIN) 警告値の下限判定に使用 049 * 警告上限(W_MAX) 警告値の上限判定に使用 050 * 異常上限(E_MAX) 異常値の上限判定に使用 051 * 052 * @og.formSample 053 * ●形式: 054 * ① <og:tableFilter classId="JUDG" /> 055 * 056 * @og.rev 5.6.6.0 (2013/07/05) keys の整合性チェックを追加 057 * 058 * @version 0.9.0 2000/10/17 059 * @author Kazuhiko Hasegawa 060 * @since JDK1.1, 061 */ 062public class TableFilter_JUDG extends AbstractTableFilter { 063 /** このプログラムのVERSION文字列を設定します。 {@value} */ 064 private static final String VERSION = "7.4.2.3 (2021/06/09)" ; 065 066 private int noVal = -1; 067 private int noJudg = -1; 068 private int noRiyu = -1; 069 070 private int noType = -1; 071 072 private int noCdrec = -1; 073 private int noEmin = -1; 074 private int noWmin = -1; 075 private int noWmax = -1; 076 private int noEmax = -1; 077 078 private DBTableModel table ; 079 080 /** 081 * デフォルトコンストラクター 082 * 083 * @og.rev 6.4.1.1 (2016/01/16) keysMap を、サブクラスから設定させるように変更。 084 */ 085 public TableFilter_JUDG() { super(); } 086 087 /** 088 * DBTableModel処理を実行します。 089 * 090 * @og.rev 7.3.1.1 (2021/02/25) USE_CSV 属性追加 091 * @og.rev 7.4.2.3 (2021/06/09) NUMBERやDECIMALフォーマットされているので書き戻す。 092 * 093 * @return 処理結果のDBTableModel 094 */ 095 public DBTableModel execute() { 096 table = getDBTableModel(); 097 if( table == null ) { return table; } // 6.4.0.5 (2016/01/09) 098 099 final ResourceManager resource = ResourceFactory.newInstance( "ja" ) ; 100 101 noVal = table.getColumnNo( "VAL" ); // 値データ(必須) 102 noJudg = table.getColumnNo( "JUDG" ); // 判定結果(必須) 103 noRiyu = table.getColumnNo( "RIYU" ); // 判定理由(必須) 104 noType = table.getColumnNo( "DATA_TYPE", false ); // 105 noCdrec = table.getColumnNo( "CDREC" , false ); // 106 noEmin = table.getColumnNo( "E_MIN" , false ); // 107 noWmin = table.getColumnNo( "W_MIN" , false ); // 108 noWmax = table.getColumnNo( "W_MAX" , false ); // 109 noEmax = table.getColumnNo( "E_MAX" , false ); // 110 111 final int rowCnt = table.getRowCount(); 112 for( int row=0; row<rowCnt; row++ ) { 113 final String[] data = table.getValues( row ); 114 115 final String val = data[noVal] ; 116 final String orgJudg = data[noJudg]; // 現在の判定結果をキープ(4:保留対応) 117 final String cdrec = rowData( row,noCdrec ,"0" ); // 登録方法 0:未決 1:不要 2:任意 4:保留 6:必須 118 // データが未設定の場合か、1:不要 2:任意 の場合は、登録方法(CDREC) をそのままセットする。 119 if( val== null || val.isEmpty() || "1".equals( cdrec ) || "2".equals( cdrec ) ) { 120 data[noJudg] = cdrec; 121 } 122 else { 123 // 判定結果(JUDG) 0:未決 1:不要 2:任意 3:合格 4:保留 5:警告 6:必須 7:不合格 124 final String dbType= rowData( row,noType,"TP_TEXT" ); // DBタイプ 未指定時は、TP_TEXT:テキスト 125 if( "TP_ON".equals( dbType ) ) { // TP_ON : 0:未決 1:OK 2:NG (3:保留) 126 if( "1".equals( val ) ){ data[noJudg] = "3"; } // 3:合格 127 else if( "0".equals( val ) ){ data[noJudg] = "0"; } // 0:未決 128 else if( "3".equals( val ) ){ data[noJudg] = "4"; } // (3:保留) は使われていないが、あれば、4:保留 129 else { data[noJudg] = "7"; } // 7:不合格 130 } 131 else if( "TP_CHECK".equals( dbType ) ) { // TP_CHECK : 1:チェック 0:未 132 if( "1".equals( val ) ) { data[noJudg] = "3"; } // 3:合格 133 // else if( "6".equals( cdrec ) ) { data[noJudg] = "6"; } // 合格以外で、登録方法が 6:必須 の場合は、6:必須 をセット 134 else { data[noJudg] = cdrec; } // 合格以外は、登録方法(CDREC) をそのままセット 135 } 136 else if( "TP_INT".equals( dbType ) || "TP_REAL".equals( dbType ) ) { 137 final double emin = rowData( row,noEmin,Double.NEGATIVE_INFINITY ); // 異常下限(E_MIN) 138 final double wmin = rowData( row,noWmin,Double.NEGATIVE_INFINITY ); // 警告下限(W_MIN) 139 final double wmax = rowData( row,noWmax,Double.POSITIVE_INFINITY ); // 警告上限(W_MAX) 140 final double emax = rowData( row,noEmax,Double.POSITIVE_INFINITY ); // 異常上限(E_MAX) 141 142 try { 143 final String numVal = StringUtil.deleteChar( val,',' ); // 7.4.2.3 (2021/06/09) NUMBERやDECIMALフォーマットされているので。 144// final double wval = Double.parseDouble( val ); // DBタイプが、TP_INTかTP_REALなので数値変換出来る 145 final double wval = Double.parseDouble( numVal ); // DBタイプが、TP_INTかTP_REALなので数値変換出来る 146 147 // 厳しい方からチェックする。 148 if( emin > wval ) { // 異常下限(E_MIN)より小さい 149 data[noJudg] = "7"; // 7:不合格 150 data[noRiyu] = String.format( "下限値(%.2f)異常 [ > %.2f ]" ,emin,wval ); 151 } 152 else if( emax < wval ) { // 異常上限(E_MAX)より大きい 153 data[noJudg] = "7"; // 7:不合格 154 data[noRiyu] = String.format( "上限値(%.2f)異常 [ < %.2f ]" ,emax,wval ); 155 } 156 else if( wmin > wval ) { // 警告下限(W_MIN)より小さい 157 data[noJudg] = "5"; // 5:警告 158 data[noRiyu] = String.format( "下限値(%.2f)警告 [ > %.2f ]" ,wmin,wval ); 159 } 160 else if( wmax < wval ) { // 警告上限(W_MAX)より大きい 161 data[noJudg] = "5"; // 5:警告 162 data[noRiyu] = String.format( "上限値(%.2f)警告 [ < %.2f ]" ,wmax,wval ); 163 } 164 else { 165 data[noJudg] = "3"; // 3:合格 166 data[noRiyu] = ""; // 判定理由のクリア 167 } 168 169 data[noVal] = numVal ; // 7.4.2.3 (2021/06/09) NUMBERやDECIMALフォーマットされているので書き戻す。 170 } 171 catch( final NumberFormatException ex ) { 172 data[noJudg] = "7"; // 7:不合格 173 data[noRiyu] = "数値変換エラー " + val ; 174 } 175 } 176 // TP_ON,TP_CHECK,TP_INT,TP_REAL 以外はDBTyleで値のチェックを行う。 177 else { 178 final DBColumn clm = resource.makeDBColumn( dbType ); 179 180 try { 181 data[noVal] = clm.valueSet( val ) ; // 7.4.2.3 (2021/06/09) 実登録データを作成して、書き戻す。 182 } 183 catch( RuntimeException ex ) { 184 ; // #valueSet(String) で、エラーが発生した場合でも、#valueCheck(String) を行うようにします。 185 } 186 187 // エラーチェック。 正常時は null 188 final ErrorMessage errMsg = clm.valueCheck( val,false ); // 厳密にチェックしない 189 if( errMsg == null || errMsg.isOK() ) { 190 data[noJudg] = "3"; // 3:合格 191 data[noRiyu] = ""; // 判定理由のクリア 192 } 193 else { 194 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ) 195 .append( "<div class='small'>" ); 196 197 for( final ErrMsg err : errMsg.toArray() ) { 198 buf.append( resource.getShortErrorMsg( err ) ); 199 } 200 data[noRiyu] = buf.append( "</div>" ).toString(); 201 202 if( errMsg.getKekka() == ErrorMessage.WARNING ) { 203 data[noJudg] = "5"; // 5:警告 204 } 205 else { // errMsg.getKekka() >= ErrorMessage.NG だが、警告以外はエラーにします。 206 data[noJudg] = "7"; // 7:不合格 207 } 208 } 209 } 210 } 211 212 // オリジナルの判定結果が、4:保留 で、5:警告か7:不合格 の場合は、4:保留 のままにしておく。 213 if( "4".equals( orgJudg ) && ( "5".equals( data[noJudg] ) || "7".equals( data[noJudg] ) ) ) { 214 data[noJudg] = "4"; // 4:保留 215 } 216 } 217 218 return table; 219 } 220 221 /** 222 * DBTableModelから、指定行-列のデータを取得します。 223 * 224 * 列番号がマイナスの場合は、カラムが存在していないため、初期値を返します。 225 * 226 * @og.rev 7.3.1.1 (2021/02/25) USE_CSV 属性追加 227 * 228 * @param row 行 229 * @param col 列 230 * @param defVal 初期値(文字列) 231 * 232 * @return 指定行-列のデータ(文字列) 233 */ 234 private String rowData( final int row , final int col , final String defVal ) { 235 String rtn = defVal ; 236 if( col >= 0 ) { 237 final String str = table.getValue( row,col ); 238 if( str != null && !str.isEmpty()) { 239 rtn = str ; 240 } 241 } 242 return rtn ; 243 } 244 245 /** 246 * DBTableModelから、指定行-列のデータを取得します。 247 * 248 * 列番号がマイナスの場合は、カラムが存在していないため、初期値を返します。 249 * 250 * @og.rev 7.3.1.1 (2021/02/25) USE_CSV 属性追加 251 * 252 * @param row 行 253 * @param col 列 254 * @param defVal 初期値(数値) 255 * 256 * @return 指定行-列のデータ(数値) 257 */ 258 private double rowData( final int row , final int col , final double defVal ) { 259 final String val = col < 0 ? null : table.getValue( row,col ) ; 260 261 try { 262 return val == null || val.isEmpty() ? defVal : Double.parseDouble( val ); 263 } 264 catch( final NumberFormatException ex ) { 265 final String errMsg = "数値項目の数値変換エラー 行=" + row + " , 列=" + col + " , 値=" + val ; 266 throw new HybsSystemException( errMsg,ex ); 267 } 268 } 269}