    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;
    027// import static org.opengion.fukurou.system.HybsConst.CR;                                              // 8.0.0.0 (2021/07/31) Delete
    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 *      ① &lt;og:tableFilter classId="JUDG" /&gt;
    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 = "8.0.0.0 (2021/08/20)" ;
    065
    066        // 8.0.0.0 (2021/07/31) ﾛｰｶﾙ変数に置き換え可能
    067//      private int noVal               = -1;
    068//      private int noJudg              = -1;
    069//      private int noRiyu              = -1;
    070
    071//      private int noType              = -1;
    072
    073//      private int noCdrec             = -1;
    074//      private int noEmin              = -1;
    075//      private int noWmin              = -1;
    076//      private int noWmax              = -1;
    077//      private int noEmax              = -1;
    078
    079        private DBTableModel table ;
    080
    081        /**
    082         * デフォルトコンストラクター
    083         *
    084         * @og.rev 6.4.1.1 (2016/01/16) keysMap を、サブクラスから設定させるように変更。
    085         */
    086        public TableFilter_JUDG() { super(); }
    087
    088        /**
    089         * DBTableModel処理を実行します。
    090         *
    091         * @og.rev 7.3.1.1 (2021/02/25) USE_CSV 属性追加
    092         * @og.rev 7.4.2.3 (2021/06/09) NUMBERやDECIMALﾌｫｰﾏｯﾄされているので書き戻す。
    093         *
    094         * @return 処理結果のDBTableModel
    095         */
    096        public DBTableModel execute() {
    097                table = getDBTableModel();
    098                if( table == null ) { return table; }                           // 6.4.0.5 (2016/01/09)
    099
    100                final ResourceManager resource = ResourceFactory.newInstance( "ja" ) ;
    101
    102                final  int noVal        = table.getColumnNo( "VAL"                              );      // 値ﾃﾞｰﾀ(必須)
    103                final  int noJudg       = table.getColumnNo( "JUDG"                             );      // 判定結果(必須)
    104                final  int noRiyu       = table.getColumnNo( "RIYU"                             );      // 判定理由(必須)
    105                final  int noType       = table.getColumnNo( "DATA_TYPE", false );      //
    106                final  int noCdrec      = table.getColumnNo( "CDREC"    , false );      //
    107                final  int noEmin       = table.getColumnNo( "E_MIN"    , false );      //
    108                final  int noWmin       = table.getColumnNo( "W_MIN"    , false );      //
    109                final  int noWmax       = table.getColumnNo( "W_MAX"    , false );      //
    110                final  int noEmax       = table.getColumnNo( "E_MAX"    , false );      //
    111
    112                final int rowCnt = table.getRowCount();
    113                for( int row=0; row<rowCnt; row++ ) {
    114                        final String[] data  = table.getValues( row );
    115
    116                        final String val     = data[noVal] ;
    117                        final String orgJudg = data[noJudg];                                    // 現在の判定結果をｷｰﾌﾟ(4:保留対応)
    118                        final String cdrec   = rowData( row,noCdrec ,"0" );             // 登録方法 0:未決 1:不要 2:任意 4:保留 6:必須
    119                        // ﾃﾞｰﾀが未設定の場合か、1:不要 2:任意 の場合は、登録方法(CDREC) をそのままセットする。
    120                        if( val== null || val.isEmpty() || "1".equals( cdrec ) || "2".equals( cdrec ) ) {
    121                                data[noJudg] = cdrec;
    122                        }
    123                        else {
    124                                // 判定結果(JUDG) 0:未決 1:不要 2:任意 3:合格 4:保留 5:警告 6:必須 7:不合格
    125                                final String dbType= rowData( row,noType,"TP_TEXT" );           // DBﾀｲﾌﾟ 未指定時は、TP_TEXT:ﾃｷｽﾄ
    126                                if( "TP_ON".equals( dbType ) ) {                                                        // TP_ON : 0:未決 1:OK 2:NG (3:保留)
    127                                        if(      "1".equals( val ) ){ data[noJudg] = "3"; }             // 3:合格
    128                                        else if( "0".equals( val ) ){ data[noJudg] = "0"; }             // 0:未決
    129                                        else if( "3".equals( val ) ){ data[noJudg] = "4"; }             // (3:保留) は使われていないが、あれば、4:保留
    130                                        else                                            { data[noJudg] = "7"; }         // 7:不合格
    131                                }
    132                                else if( "TP_CHECK".equals( dbType ) ) {                                        // TP_CHECK : 1:ﾁｪｯｸ 0:未
    133                                        if(      "1".equals( val ) )    { data[noJudg] = "3"; } // 3:合格
    134                //                      else if( "6".equals( cdrec ) )  { data[noJudg] = "6"; } // 合格以外で、登録方法が 6:必須 の場合は、6:必須 をｾｯﾄ
    135                                        else                                            { data[noJudg] = cdrec; }       // 合格以外は、登録方法(CDREC) をそのままセット
    136                                }
    137                                else if( "TP_INT".equals( dbType ) || "TP_REAL".equals( dbType ) ) {
    138                                        final double emin = rowData( row,noEmin,Double.NEGATIVE_INFINITY );             // 異常下限(E_MIN)
    139                                        final double wmin = rowData( row,noWmin,Double.NEGATIVE_INFINITY );             // 警告下限(W_MIN)
    140                                        final double wmax = rowData( row,noWmax,Double.POSITIVE_INFINITY );             // 警告上限(W_MAX)
    141                                        final double emax = rowData( row,noEmax,Double.POSITIVE_INFINITY );             // 異常上限(E_MAX)
    142
    143                                        try {
    144                                                final String numVal = StringUtil.deleteChar( val,',' );                         // 7.4.2.3 (2021/06/09) NUMBERやDECIMALﾌｫｰﾏｯﾄされているので。
    145//                                              final double wval = Double.parseDouble( val );          // DBﾀｲﾌﾟが、TP_INTかTP_REALなので数値変換出来る
    146                                                final double wval = Double.parseDouble( numVal );       // DBﾀｲﾌﾟが、TP_INTかTP_REALなので数値変換出来る
    147
    148                                                // 厳しい方からﾁｪｯｸする。
    149                                                if( emin > wval ) {                     // 異常下限(E_MIN)より小さい
    150                                                        data[noJudg] = "7";             // 7:不合格
    151                                                        data[noRiyu] = String.format( "下限値(%.2f)異常 [ ＞ %.2f ]" ,emin,wval );
    152                                                }
    153                                                else if( emax < wval ) {        // 異常上限(E_MAX)より大きい
    154                                                        data[noJudg] = "7";             // 7:不合格
    155                                                        data[noRiyu] = String.format( "上限値(%.2f)異常 [ ＜ %.2f ]" ,emax,wval );
    156                                                }
    157                                                else if( wmin > wval ) {        // 警告下限(W_MIN)より小さい
    158                                                        data[noJudg] = "5";             // 5:警告
    159                                                        data[noRiyu] = String.format( "下限値(%.2f)警告 [ ＞ %.2f ]" ,wmin,wval );
    160                                                }
    161                                                else if( wmax < wval ) {        // 警告上限(W_MAX)より大きい
    162                                                        data[noJudg] = "5";             // 5:警告
    163                                                        data[noRiyu] = String.format( "上限値(%.2f)警告 [ ＜ %.2f ]" ,wmax,wval );
    164                                                }
    165                                                else {
    166                                                        data[noJudg] = "3";             // 3:合格
    167                                                        data[noRiyu] = "";              // 判定理由のｸﾘｱ
    168                                                }
    169
    170                                                data[noVal] = numVal ;          // 7.4.2.3 (2021/06/09) NUMBERやDECIMALﾌｫｰﾏｯﾄされているので書き戻す。
    171                                        }
    172                                        catch( final NumberFormatException ex ) {
    173                                                data[noJudg] = "7";                     // 7:不合格
    174                                                data[noRiyu] = "数値変換ｴﾗｰ " + val ;
    175                                        }
    176                                }
    177                                // TP_ON,TP_CHECK,TP_INT,TP_REAL 以外はDBTyleで値のﾁｪｯｸを行う。
    178                                else {
    179                                        final DBColumn clm = resource.makeDBColumn( dbType );
    180
    181                                        try {
    182                                                data[noVal] = clm.valueSet( val ) ;             // 7.4.2.3 (2021/06/09) 実登録データを作成して、書き戻す。
    183                                        }
    184                                        catch( RuntimeException ex ) {
    185                                                System.err.println( ex.getMessage() );  // 8.0.0.0 (2021/07/31)
    186//                                              ;       // #valueSet(String) で、ｴﾗｰが発生した場合でも、#valueCheck(String) を行うようにします。
    187                                        }
    188
    189                                        // エラーﾁｪｯｸ。 正常時は null
    190                                        final ErrorMessage errMsg = clm.valueCheck( val,false );                        // 厳密にチェックしない
    191                                        if( errMsg == null || errMsg.isOK() ) {
    192                                                data[noJudg] = "3";             // 3:合格
    193                                                data[noRiyu] = "";              // 判定理由のｸﾘｱ
    194                                        }
    195                                        else {
    196                                                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
    197                                                                                .append( "<div class='small'>" );
    198
    199                                                for( final ErrMsg err : errMsg.toArray() ) {
    200                                                        buf.append( resource.getShortErrorMsg( err ) );
    201                                                }
    202                                                data[noRiyu] = buf.append( "</div>" ).toString();
    203
    204                                                if( errMsg.getKekka() == ErrorMessage.WARNING ) {
    205                                                        data[noJudg] = "5";             // 5:警告
    206                                                }
    207                                                else {                                          // errMsg.getKekka() >= ErrorMessage.NG だが、警告以外はｴﾗｰにします。
    208                                                        data[noJudg] = "7";             // 7:不合格
    209                                                }
    210                                        }
    211                                }
    212                        }
    213
    214                        // ｵﾘｼﾞﾅﾙの判定結果が、4:保留 で、5:警告か7:不合格 の場合は、4:保留 のままにしておく。
    215                        if( "4".equals( orgJudg ) && ( "5".equals( data[noJudg] ) || "7".equals( data[noJudg] ) ) ) {
    216                                data[noJudg] = "4";             // 4:保留
    217                        }
    218                }
    219
    220                return table;
    221        }
    222
    223        /**
    224         * DBTableModelから、指定行-列のデータを取得します。
    225         *
    226         * 列番号がマイナスの場合は、ｶﾗﾑが存在していないため、初期値を返します。
    227         *
    228         * @og.rev 7.3.1.1 (2021/02/25) USE_CSV 属性追加
    229         * @og.rev 8.0.0.0 (2021/08/20) spotbugs:Bug kind and pattern: UwF - UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR
    230         *
    231         * @param       row 行
    232         * @param       col 列
    233         * @param       defVal 初期値(文字列)
    234         *
    235         * @return 指定行-列のデータ(文字列)
    236         */
    237        private String rowData( final int row , final int col , final String defVal ) {
    238                String rtn = defVal ;
    239//              if( col >= 0 ) {
    240                if( col >= 0 && table != null ) {               // 8.0.0.0 (2021/08/20) spotbugs
    241                        final String val = table.getValue( row,col );
    242                        if( val != null && !val.isEmpty()) {
    243                                rtn = val ;
    244                        }
    245                }
    246                return rtn ;
    247        }
    248
    249        /**
    250         * DBTableModelから、指定行-列のデータを取得します。
    251         *
    252         * 列番号がマイナスの場合は、ｶﾗﾑが存在していないため、初期値を返します。
    253         *
    254         * @og.rev 7.3.1.1 (2021/02/25) USE_CSV 属性追加
    255         * @og.rev 8.0.0.0 (2021/08/20) spotbugs:Bug kind and pattern: UwF - UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR
    256         *
    257         * @param       row 行
    258         * @param       col 列
    259         * @param       defVal 初期値(数値)
    260         *
    261         * @return 指定行-列のデータ(数値)
    262         */
    263        private double rowData( final int row , final int col , final double defVal ) {
    264                double rtn = defVal ;
    265                if( col >= 0 && table != null ) {               // 8.0.0.0 (2021/08/20) spotbugs
    266                        final String val = table.getValue( row,col );
    267                        if( val != null && !val.isEmpty()) {
    268                                try {
    269                                        rtn = Double.parseDouble( val ) ;
    270                                }
    271                                catch( final NumberFormatException ex ) {
    272                                        final String errMsg = "数値項目の数値変換ｴﾗｰ　行=" + row + " , 列=" + col + " , 値=" + val ;
    273                                        throw new HybsSystemException( errMsg,ex );
    274                                }
    275                        }
    276                }
    277                return rtn ;
    278
    279//              final String val = col < 0 ? null : table.getValue( row,col ) ;
    280//
    281//              try {
    282//                      return val == null || val.isEmpty() ? defVal : Double.parseDouble( val );
    283//              }
    284//              catch( final NumberFormatException ex ) {
    285//                      final String errMsg = "数値項目の数値変換ｴﾗｰ　行=" + row + " , 列=" + col + " , 値=" + val ;
    286//                      throw new HybsSystemException( errMsg,ex );
    287//              }
    288        }
    289}