    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 java.util.stream.Stream;                                                                 // 7.3.1.1 (2021/02/25)
    019import java.util.stream.Collectors;                                                             // 7.3.1.1 (2021/02/25)
    020
    021import org.opengion.hayabusa.db.AbstractTableFilter;
    022import org.opengion.hayabusa.db.DBTableModel;
    023import org.opengion.hayabusa.resource.ResourceFactory;
    024import org.opengion.hayabusa.resource.ResourceManager;
    025import org.opengion.fukurou.util.ErrorMessage;
    026import org.opengion.fukurou.util.StringUtil;
    027
    028/**
    029 * TableFilter_LABEL は、TableFilter インターフェースを継承した、DBTableModel 処理用の
    030 * 実装クラスです。
    031 *
    032 * ここでは、キーのCLM,LBL と、LANG より、ラベルリソースに変換した値を設定します。
    033 * ラベルの設定は、設定先の値が NULL/空文字か、カラム名と同じ(無変換セット)の場合のみセットされます。
    034 *
    035 * パラメータは、tableFilterタグの keys, vals にそれぞれ記述するか、BODY 部にCSS形式で記述します。
    036 * 【パラメータ】
    037 *  {
    038 *       SYSTEM_ID  : ラベルリソースの作成システムIDを指定します。無指定時は、ログイン時のリソースになります。
    039 *       LANG       : ラベルリソースの言語を指定します。無指定時は、日本語になります。
    040 *       CLM        : ラベルリソースのキーとなる値が設定されているカラム名を指定します。
    041 *       LBL        : CLMで指定されたカラム名から値を取り出し、ラベルリソースに変換した結果をセットします。
    042 *       LLBL       : 同上（ラベル長）                                                                  7.2.9.0 (2020/10/12)
    043 *       SLBL       : 同上（ラベル短）                                                                  7.2.9.0 (2020/10/12)
    044 *       DISC       : 同上（概要）                                                                            7.2.9.0 (2020/10/12)
    045 *       LRAW       : 同上（長生ラベル）                                                         7.2.9.0 (2020/10/12)
    046 *       SRAW       : 同上（短生ラベル）                                                         7.2.9.0 (2020/10/12)
    047 *       MSG        : 同上（引数付きラベル）                                                       7.2.9.1 (2020/10/23)
    048 *       USE_CSV    : true:CLMの設定値がCSV形式/false:通常の単独ｶﾗﾑ         7.3.1.1 (2021/02/25)
    049 *  }
    050 *
    051 * 5.7.8.0 (2014/07/04) 解除
    052 * CLM と LBL に同じカラムを指定すると、このフィルターを通過するたびに、変換後のラベルが
    053 * 再びキーとして変換しようと試みることになります。不測の事態に陥る可能性があるため、
    054 * その様な設定は出来なくなっています。
    055 *
    056 * 5.7.8.0 (2014/07/04) CLM と LBL に同じカラムを指定する事ができます。
    057 *
    058 * また、CLM または LBL で指定したカラムが DBTableModel に存在しない場合は、処理そのものを
    059 * 無視します。その場合は、警告も出力されませんので、ご注意ください。
    060 *
    061 * 7.2.9.0 (2020/10/12) LLBL,SLBL,DISC,RLBL 属性追加。
    062 *
    063 * 7.2.9.1 (2020/10/23) MSG 属性追加。
    064 *   引数付きなので、VALS 指定時に、セットするカラム名に引数として渡したいパラメータをスペースで繋げます。
    065 *   パラメータは、@カラム名 か、そのままの値で指定します。
    066 *
    067 * 7.3.1.1 (2021/02/25) USE_CSV 属性追加。
    068 *   true:CLMの設定値がCSV形式/false:通常の単独ｶﾗﾑ
    069 *   ただし、LRAW,SRAW,MSG については、変換しません。
    070 *
    071 * @og.formSample
    072 * ●形式：
    073 *      ① &lt;og:tableFilter classId="LABEL" keys="CLM,LBL" vals="COLUMN,LABEL_CLM" /&gt;
    074 *
    075 *      ② &lt;og:tableFilter classId="LABEL" &gt;
    076 *               {
    077 *                      SYSTEM_ID  : GF ;
    078 *                      LANG       : ja ;
    079 *                      CLM        : COLUMN ;
    080 *                      LBL        : LABEL_CLM ;
    081 *               }
    082 *         &lt;/og:tableFilter&gt;
    083 *
    084 * @og.rev 5.6.6.0 (2013/07/05) keys の整合性チェックを追加
    085 *
    086 * @version  0.9.0  2000/10/17
    087 * @author   Kazuhiko Hasegawa
    088 * @since    JDK1.1,
    089 */
    090public class TableFilter_LABEL extends AbstractTableFilter {
    091        /** このプログラムのVERSION文字列を設定します。   {@value} */
    092        private static final String VERSION = "7.3.1.1 (2021/02/25)" ;
    093
    094        /**
    095         * デフォルトコンストラクター
    096         *
    097         * @og.rev 6.4.1.1 (2016/01/16) keysMap を、サブクラスから設定させるように変更。
    098         */
    099        public TableFilter_LABEL() {
    100                super();
    101                initSet( "SYSTEM_ID"    , "システムIDを指定します(初期値:ログイン時のリソース)"                );
    102                initSet( "LANG"                 , "言語を指定(初期値:日本語)"                                                              );
    103                initSet( "CLM"                  , "キーとなる値が設定されているカラム名を指定"                               );
    104                initSet( "LBL"                  , "ラベルリソースに変換した結果をセットするカラム名を指定" );
    105                initSet( "LLBL"                 , "同上（ラベル長）"                                                                            );              // 7.2.9.0 (2020/10/12)
    106                initSet( "SLBL"                 , "同上（ラベル短）"                                                                            );              // 7.2.9.0 (2020/10/12)
    107                initSet( "DISC"                 , "同上（概要）       "                                                                                       );              // 7.2.9.0 (2020/10/12)
    108                initSet( "LRAW"                 , "同上（長生ラベル）"                                                                           );              // 7.2.9.0 (2020/10/12)
    109                initSet( "SRAW"                 , "同上（短生ラベル）"                                                                           );              // 7.2.9.0 (2020/10/12)
    110                initSet( "MSG"                  , "同上（引数付きラベル）"                                                                 );              // 7.2.9.1 (2020/10/23)
    111                initSet( "USE_CSV"              , "true:CLMの設定値がCSV形式/false:通常の単独ｶﾗﾑ"                   );              // 7.3.1.1 (2021/02/25)
    112        }
    113
    114        /**
    115         * DBTableModel処理を実行します。
    116         *
    117         * @og.rev 5.5.2.2 (2012/05/09) SYSTEM_ID を受け取るように変更
    118         * @og.rev 5.5.2.6 (2012/05/25) protected変数を、private化したため、getterメソッドで取得するように変更
    119         * @og.rev 5.7.8.0 (2014/07/04) CLM と LBL に同じカラムを指定できるように変更
    120         * @og.rev 6.4.0.5 (2016/01/09) LBLが、nullか、または、CLMと同じ場合は、ﾘｿｰｽから、そうでない場合は、LBLの値を使用します。
    121         * @og.rev 6.5.0.1 (2016/10/21) ErrorMessage をまとめるのと、直接 Throwable を渡します。
    122         * @og.rev 7.2.9.0 (2020/10/12) LLBL,SLBL,DISC,RLBL 属性追加
    123         * @og.rev 7.2.9.1 (2020/10/23) MSG 属性追加
    124         * @og.rev 7.3.1.1 (2021/02/25) USE_CSV 属性追加
    125         *
    126         * @return 処理結果のDBTableModel
    127         */
    128        public DBTableModel execute() {
    129                final DBTableModel table = getDBTableModel();                   // 5.5.2.6 (2012/05/25) インターフェースにgetterメソッド追加
    130
    131                if( table == null ) { return table; }                                   // 6.4.0.5 (2016/01/09)
    132
    133                final String systemId   = getValue( "SYSTEM_ID" );              // 5.5.2.2 (2012/05/09)
    134                final String lang               = getValue( "LANG" );
    135                final ResourceManager resource = ResourceFactory.newInstance( systemId,lang,false );            // 5.5.2.2 (2012/05/09)
    136
    137                final String clm  = getValue( "CLM" );
    138                final String lbl  = getValue( "LBL" );
    139                final String llbl = getValue( "LLBL" );                                         // 7.2.9.0 (2020/10/12)
    140                final String slbl = getValue( "SLBL" );                                         // 7.2.9.0 (2020/10/12)
    141                final String disc = getValue( "DISC" );                                         // 7.2.9.0 (2020/10/12)
    142                final String lraw = getValue( "LRAW" );                                         // 7.2.9.0 (2020/10/12)
    143                final String sraw = getValue( "SRAW" );                                         // 7.2.9.0 (2020/10/12)
    144
    145                final boolean useCSV = StringUtil.nval( getValue( "USE_CSV" ),false );  // 7.3.1.1 (2021/02/25)
    146
    147                final int clmNo   = table.getColumnNo( clm,false );                     // 存在しない場合は、-1 を返す。
    148                final int lblNo   = table.getColumnNo( lbl,false );
    149                final int llblNo  = table.getColumnNo( llbl,false );            // 7.2.9.0 (2020/10/12)
    150                final int slblNo  = table.getColumnNo( slbl,false );            // 7.2.9.0 (2020/10/12)
    151                final int discNo  = table.getColumnNo( disc,false );            // 7.2.9.0 (2020/10/12)
    152                final int lrawNo  = table.getColumnNo( lraw,false );            // 7.2.9.0 (2020/10/12)
    153                final int srawNo  = table.getColumnNo( sraw,false );            // 7.2.9.0 (2020/10/12)
    154
    155                // 7.2.9.1 (2020/10/23) MSGの値は、セットするカラム名の後ろに、パラメータをスペースで繋げています。
    156                final String msg_prm = getValue( "MSG" );
    157                final int   msgNo ;
    158                final int[] prmNo ;
    159                final String[] prmVal ;
    160
    161                if( msg_prm != null ) {
    162                        final String[] msgs = msg_prm.split( "[\\s]+" );                // 連続スペース、タブを区切り文字にする。
    163                        msgNo = table.getColumnNo( msgs[0],false );
    164                        prmNo  = new int[msgs.length-1];
    165                        prmVal = new String[msgs.length-1];
    166                        for( int i=1; i<msgs.length; i++ ) {
    167                                prmVal[i-1] = msgs[i];                                                          // 元の引数をそのまま使う可能性があるので、セットしておく。
    168
    169                                if( '@' == msgs[i].charAt(0) ) {                                        // ｶﾗﾑ指定の意味
    170                                        prmNo[i-1] = table.getColumnNo( msgs[i].substring(1),false );
    171                                }
    172                                else {
    173                                        prmNo[i-1] = -1;
    174                                }
    175                        }
    176                }
    177                else {
    178                        msgNo  = -1;
    179                        prmNo  = null;
    180                        prmVal = null;
    181                }
    182
    183                // 5.7.8.0 (2014/07/04) CLM と LBL に同じカラムを指定できるように変更
    184//              if( clmNo >= 0 && lblNo >= 0 ) {
    185//              if( clmNo >= 0 && ( lblNo >= 0 || llblNo >= 0 || slblNo >= 0 || discNo >= 0 || lrawNo >= 0 || srawNo >= 0 ) ) {                                 // 7.2.9.0 (2020/10/12)
    186                if( clmNo >= 0 && ( lblNo >= 0 || llblNo >= 0 || slblNo >= 0 || discNo >= 0 || lrawNo >= 0 || srawNo >= 0 || msgNo >= 0 ) ) {   // 7.2.9.1 (2020/10/23)
    187                        String[] data  = null;
    188                        final int rowCnt = table.getRowCount();
    189                        for( int row=0; row<rowCnt; row++ ) {
    190                                String clmVal = null;
    191                                try {
    192                                        data   = table.getValues( row );
    193                                        clmVal = data[clmNo];           // 変換する元のカラム名
    194
    195                                        if( lblNo >= 0 ) {
    196                                                final String lblVal = data[lblNo];              // 変換する元のラベル            6.4.0.5 (2016/01/09)
    197                                                // 6.4.0.5 (2016/01/09) LBLが、nullか、または、CLMと同じ場合は、ﾘｿｰｽから、そうでない場合は、LBLの値を使用します。
    198                                                // つまり、上記の条件が成立した場合は、LBLを書き換えないということです。
    199                                                if( StringUtil.isNull( lblVal ) || lblVal.equals( clmVal ) ) {
    200                                                        if( useCSV ) {                                          // 7.3.1.1 (2021/02/25)
    201                                                                data[lblNo] = Stream.of( clmVal.split(",") )
    202                                                                                                        .map( clmv -> resource.getLabel( clmv ) )
    203                                                                                                        .collect( Collectors.joining( "," ) );
    204                                                        }
    205                                                        else {
    206                                                                data[lblNo] = resource.getLabel( clmVal ) ;
    207                                                        }
    208                                                }
    209                                        }
    210
    211                                        // 7.2.9.0 (2020/10/12) LLBL,SLBL,DISC,RLBL 属性追加
    212                                        if( llblNo >= 0 ) {
    213                                                final String llblVal = data[llblNo];            // 変換する元のラベル            6.4.0.5 (2016/01/09)
    214                                                if( StringUtil.isNull( llblVal ) || llblVal.equals( clmVal ) ) {
    215                                                        if( useCSV ) {                                          // 7.3.1.1 (2021/02/25)
    216                                                                data[llblNo] = Stream.of( clmVal.split(",") )
    217                                                                                                        .map( clmv -> resource.getLongLabel( clmv ) )
    218                                                                                                        .collect( Collectors.joining( "," ) );
    219                                                        }
    220                                                        else {
    221                                                                data[llblNo] = resource.getLongLabel( clmVal ) ;
    222                                                        }
    223                                                }
    224                                        }
    225
    226                                        if( slblNo >= 0 ) {
    227                                                final String slblVal = data[slblNo];            // 変換する元のラベル            6.4.0.5 (2016/01/09)
    228                                                if( StringUtil.isNull( slblVal ) || slblVal.equals( clmVal ) ) {
    229                                                        if( useCSV ) {                                          // 7.3.1.1 (2021/02/25)
    230                                                                data[slblNo] = Stream.of( clmVal.split(",") )
    231                                                                                                        .map( clmv -> resource.getShortLabel( clmv ) )
    232                                                                                                        .collect( Collectors.joining( "," ) );
    233                                                        }
    234                                                        else {
    235                                                                data[slblNo] = resource.getShortLabel( clmVal ) ;
    236                                                        }
    237                                                }
    238                                        }
    239
    240                                        // 7.2.9.0 (2020/10/12) SLBL,DISC,RLBL 属性追加
    241                                        if( discNo >= 0 ) {
    242                                                final String discVal = data[discNo];            // 変換する元のラベル            6.4.0.5 (2016/01/09)
    243                                                if( StringUtil.isNull( discVal ) || discVal.equals( clmVal ) ) {
    244                                                        if( useCSV ) {                                          // 7.3.1.1 (2021/02/25)
    245                                                                data[discNo] = Stream.of( clmVal.split(",") )
    246                                                                                                        .map( clmv -> resource.getDescription( clmv ) )
    247                                                                                                        .collect( Collectors.joining( "," ) );
    248                                                        }
    249                                                        else {
    250                                                                data[discNo] = resource.getDescription( clmVal ) ;
    251                                                        }
    252                                                }
    253                                        }
    254
    255                                        // 7.2.9.0 (2020/10/12) SLBL,DISC,RLBL 属性追加
    256                                        if( lrawNo >= 0 ) {
    257                                                final String lrawVal = data[lrawNo];            // 変換する元のラベル            6.4.0.5 (2016/01/09)
    258                                                if( StringUtil.isNull( lrawVal ) || lrawVal.equals( clmVal ) ) {
    259                                                        final String val = resource.getRawLongLabel( clmVal ) ;
    260                                                        data[lrawNo] = val == null || val.equals( clmVal ) ? "" : val ;         // null時はkeyが返ってくるので 空文字 を返す。
    261                                                }
    262                                        }
    263
    264                                        // 7.2.9.0 (2020/10/12) SLBL,DISC,RLBL 属性追加
    265                                        if( srawNo >= 0 ) {
    266                                                final String srawVal = data[srawNo];            // 変換する元のラベル            6.4.0.5 (2016/01/09)
    267                                                if( StringUtil.isNull( srawVal ) || srawVal.equals( clmVal ) ) {
    268                                                        final String val = resource.getRawShortLabel( clmVal,false ) ;          // null時は 空文字 を返す。
    269                                                        data[srawNo] = val == null || val.equals( clmVal ) ? "" : val;          // null時は 空文字 を返す。
    270
    271//                                                      data[srawNo] = resource.getRawShortLabel( clmVal,false ) ;                      // null時は 空文字 を返す。
    272                                                }
    273                                        }
    274
    275                                        // 7.2.9.1 (2020/10/23) MSG 属性追加
    276                                        if( msgNo >= 0 ) {
    277                                                final String msgVal = data[msgNo];
    278                                                if( StringUtil.isNull( msgVal ) || msgVal.equals( clmVal ) ) {
    279                                                        final String[] prmVals = new String[prmNo.length];
    280                                                        for( int i=0; i<prmNo.length; i++ ) {
    281                                                                if( prmNo[i] >= 0 ) {
    282                                                                        prmVals[i] = StringUtil.nval( data[prmNo[i]] , "" );
    283                                                                }
    284                                                                else {
    285                                                                        prmVals[i] = prmVal[i];
    286                                                                }
    287                                                        }
    288
    289                                                        data[msgNo] = resource.getLabel( clmVal,prmVals ) ;
    290                                                }
    291                                        }
    292                                }
    293                                catch( final RuntimeException ex ) {
    294                                        // 6.5.0.1 (2016/10/21) ErrorMessage をまとめるのと、直接 Throwable を渡します。
    295                                        makeErrorMessage( "TableFilter_LABEL Error",ErrorMessage.NG )
    296                                                .addMessage( row+1,ErrorMessage.NG,"LABEL"
    297                                                        , "CLM=[" + clm + "],VAL=[" + clmVal + "]"
    298                                                        , StringUtil.array2csv( data )
    299                                                )
    300                                                .addMessage( ex );
    301                                }
    302                        }
    303                }
    304
    305                return table;
    306        }
    307}