    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.html;
    017
    018import org.opengion.fukurou.system.OgRuntimeException ;                 // 6.4.2.0 (2016/01/29)
    019import static org.opengion.fukurou.system.HybsConst.CR ;                // 6.1.0.0 (2014/12/26)
    020import org.opengion.fukurou.util.StringUtil;
    021import org.opengion.fukurou.model.Formatter;
    022import org.opengion.hayabusa.common.HybsSystemException;
    023import org.opengion.hayabusa.db.DBTableModel;
    024
    025import java.util.regex.Pattern;
    026import java.util.regex.Matcher;
    027import java.util.stream.IntStream;                                                              // 6.4.3.4 (2016/03/11)
    028
    029/**
    030 * [PN],[OYA] などの [] で指定されたカラムで表されたフォーマットデータに対して、
    031 * DBTableModelオブジェクトを適用して 各カラムに実データを割り当てるオブジェクトです。
    032 *
    033 * 特に、[XXXX]に対して、[#XXXX]、[$XXXX]、[!XXXX]などの特殊記号が使用できます。
    034 * 特殊記号の解釈は、HTMLFormatTextField系とHTMLFormatTable系で異なりますので
    035 * ご注意ください。
    036 *
    037 * '#':ラベルのみ  '$':レンデラー '!':値のみ
    038 *
    039 * @og.rev 3.5.4.0 (2003/11/25) 新規追加
    040 * @og.group 画面表示
    041 *
    042 * @version  4.0
    043 * @author   Kazuhiko Hasegawa
    044 * @since    JDK5.0,
    045 */
    046public class TableFormatter {
    047
    048        /** フォーマットタイプの指定の特殊なマーク {@value} */
    049        public static final String HYBS_ITD_MARKER = "h_itd_marker";
    050        // 4.3.2.0 (2008/09/10) </td>前のスペースを取り消す。
    051        private static final Pattern PTN_KEY = Pattern.compile( "[ \t]+</td" );                 // 6.4.1.1 (2016/01/16) ptnKey → PTN_KEY refactoring
    052
    053        private FormatterType   formatType      ;
    054        private int[]                   location        ;
    055        private String[]                format          ;
    056        private String                  formatTag       ;
    057        private String                  rowspan         = " rowspan=\"2\"";
    058        private String                  trTag           ;
    059        private boolean                 noClass         ;
    060        // 3.5.6.0 (2004/06/18) '!' 値のみ 追加 既存の '$' は、レンデラー
    061        private char[]                  type            ;                       // '#':ラベルのみ  '$':レンデラー '!':値のみ  その他:通常
    062        private String                  usableKey       ;                       // キー情報のカラム文字列
    063        private int                             usableKeyNo     = -1;           // キー情報のカラム番号
    064        private String                  usableList      = "1";
    065
    066        private String                  keyBreakClm     ;                       // 5.7.6.3 (2014/05/23) キーブレイクをチェックするカラムID
    067        private int                             breakClmNo      = -1;           // 5.7.6.3 (2014/05/23) キーブレイクカラム番号
    068        private String                  breakVal        ;                       // 5.7.6.3 (2014/05/23) キーブレイクをチェックする値
    069
    070        private String                  itdBody         = "";           // 3.5.6.0 (2004/06/18) 追加
    071        private Formatter               formatter       ;
    072
    073        /**
    074         * デフォルトコンストラクター
    075         *
    076         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    077         */
    078        public TableFormatter() { super(); }            // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    079
    080        /**
    081         * フォーマットをセットします。
    082         * フォーマットに、&lt;table&gt;を含む場合、TextField扱いなので、フォーマット分割
    083         * しません。table を含まず、tr を含む場合は、１行分のデータとして扱う為、
    084         * trTag を求めます。
    085         * trTag と format との間に、行ヘッダーが入ります。
    086         * Tomcat6では、JSPのパース時に、tabやspaceはそのままパースされるため、&lt;/td&gt;前
    087         * のスペース削除処理も行います。
    088         *
    089         * @og.rev 4.3.2.0 (2008/09/10) &lt;/td&gt;前のスペースを取り消します。
    090         * @og.rev 5.5.0.3 (2012/03/13) &lt;tr&gt;を取らないフラグ追加
    091         *
    092         * @param       fmt  [カラム名] 形式のフォーマットデータ
    093         * @param   flag  falseにすると先頭のtrタグを取る処理を行いません(5.5.0.3)
    094         */
    095        public void setFormat( final String fmt , final boolean flag ) {
    096                final int tbl = fmt.indexOf( "<table" );
    097                final int str = fmt.indexOf( "<tr" );
    098
    099                // tr を含み、かつ、tableを含まないか、含んでも tr の後ろにtableがある場合。
    100                if( str >= 0 && ( tbl < 0 || str < tbl ) && flag ) { // 5.5.0.3(2012/03/13)
    101                        final int end = fmt.indexOf( '>',str );
    102                        formatTag = fmt.substring(end+1);
    103                        trTag = fmt.substring(0,end+1) ;
    104                }
    105                else {
    106                        formatTag = fmt;
    107                        trTag     = null;
    108                }
    109                // 4.3.2.0 (2008/09/10) </td>前のスペースを取り消す。
    110                final Matcher matcher = PTN_KEY.matcher( formatTag );
    111                formatTag = matcher.replaceAll( "</td" );
    112        }
    113
    114        /**
    115         * フォーマットをセットします。
    116         * フォーマットに、&lt;table&gt;を含む場合、TextField扱いなので、フォーマット分割
    117         * しません。table を含まず、tr を含む場合は、１行分のデータとして扱う為、
    118         * trTag を求めます。
    119         * trTag と format との間に、行ヘッダーが入ります。
    120         * Tomcat6では、JSPのパース時に、tabやspaceはそのままパースされるため、&lt;/td&gt;前
    121         * のスペース削除処理も行います。
    122         *
    123         * @og.rev 5.5.0.3 (2012/03/13) 引数追加につき。
    124         *
    125         * @param       fmt  [カラム名] 形式のフォーマットデータ
    126         */
    127        public void setFormat( final String fmt ) {
    128                setFormat( fmt , true );
    129        }
    130
    131        /**
    132         * フォーマットを取得します。
    133         *
    134         * @og.rev 3.5.5.8 (2004/05/20) 新規追加
    135         * @og.rev 5.1.7.0 (2010/06/01) サニタイズ戻し処理("\\]\\"から"["に戻し)を追加
    136         *
    137         * @return      フォーマットデータ
    138         */
    139        public String getFormat() {
    140                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
    141                // 反転注意
    142                return trTag == null ? decodeSanitizedStr( formatTag ) : decodeSanitizedStr( trTag + formatTag );
    143        }
    144
    145        /**
    146         * DBTableModelを利用して、フォーマットデータを初期化します。
    147         *
    148         * @og.rev 3.5.5.0 (2004/03/12) [KEY.カラム名] 機能追加
    149         * @og.rev 3.5.5.2 (2004/04/02) [I] で、行番号を作成します。
    150         * @og.rev 3.5.6.0 (2004/06/18) '!' 値のみ 追加 既存の '$' は、レンデラー
    151         * @og.rev 3.6.0.0 (2004/09/17) [ROW.ID] で、行毎のチェックボックスのIDを返します。
    152         * @og.rev 5.1.7.0 (2010/06/01) サニタイズ戻し処理("\\]\\"から"["に戻し)を追加
    153         * @og.rev 5.7.6.3 (2014/05/23) キーブレイクをチェックする keyBreakClm 属性追加
    154         * @og.rev 6.4.3.4 (2016/03/11) Formatterに新しいコンストラクターを追加する。
    155         *
    156         * @param       table   DBTableModelオブジェクト
    157         */
    158        public void makeFormat( final DBTableModel table ) {
    159                formatter = new Formatter( table,formatTag );           // 6.4.3.4 (2016/03/11)
    160                location = formatter.getClmNos();
    161                format   = formatter.getFormat();
    162
    163                // 5.1.7.0 (2010/06/01) サニタイズ戻し処理("\\]\\"から"["に戻し)を追加
    164                // 6.0.2.5 (2014/10/31)  null でないことがわかっている値の冗長な null チェックがあります。
    165                        for( int i=0; i<format.length; i++ ) {
    166                                format[i] = decodeSanitizedStr( format[i] );
    167                        }
    168
    169                type = formatter.getType();
    170
    171                // このフォーマットを使用するかどうかを指定する判定条件の初期設定です。
    172                if( usableKey != null ) {
    173                        usableKeyNo = table.getColumnNo( usableKey );
    174                }
    175
    176                // 5.7.6.3 (2014/05/23) キーブレイクをチェックする keyBreakClm 属性追加
    177                if( keyBreakClm != null ) {
    178                        breakClmNo = table.getColumnNo( keyBreakClm );
    179                        breakVal   = null;              // 初期化します。
    180                }
    181        }
    182
    183        /**
    184         * テーブルフォーマットのタイプを指定します。
    185         * enum FormatterType で、指定します。
    186         *
    187         * @og.rev 4.0.0.0 (2007/05/02) enum 定義に変更
    188         *
    189         * @param  ftype フォーマットのタイプ
    190         */
    191        public void setFormatType( final FormatterType ftype ) {
    192                formatType = ftype;
    193        }
    194
    195        /**
    196         * このフォーマットのタイプを返します。
    197         *
    198         * このフォーマットのタイプを返します。
    199         *
    200         * @og.rev 4.0.0.0 (2007/05/02) enum 定義に変更
    201         *
    202         * @return      このフォーマットのタイプを返します。
    203         */
    204        public FormatterType getFormatType() {
    205                return formatType;
    206        }
    207
    208        /**
    209         * テーブルの rowspan 属性をセットします。
    210         * rowspan は、ヘッダー部のフォーマットの行数です。初期値は ２行 です。
    211         * 設定は、"2" などの、数字部のみをセットします。
    212         *
    213         * @param  rowspan 属性
    214         */
    215        public void setRowspan( final String rowspan ) {
    216                if( rowspan == null || rowspan.isEmpty() || rowspan.equals( "1" ) ) {
    217                        this.rowspan = "";
    218                }
    219                else {
    220                        this.rowspan = " rowspan=\"" + rowspan + "\"";
    221                }
    222        }
    223
    224        /**
    225         * 設定された rowspan を返します。
    226         * これは、フォーマットの段組の数を取り出します。
    227         * 文字列としては、rowspan="2" という形で取り出します。
    228         *
    229         * @return フォーマット文字列
    230         */
    231        public String getRowspan() {
    232                return rowspan;
    233        }
    234
    235        /**
    236         * ロケーション番号のサイズを返します。
    237         * フォーム位置番号は、0 から getLocationSize()-1 までの数字を指定します。
    238         * ロケーションサイズは、aaa[ABC]bbb[DEF]ccc[GHI]ddd となっている場合、
    239         * aaa , bbb , ccc , ddd は、フォーマットで、サイズは４。
    240         * ABC , DEF , GHI に対応するカラム番号がロケーションで、サイズは３。
    241         * このメソッドで返すのは、ロケーション番号(３)の方です。
    242         *
    243         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    244         *
    245         * @return  ロケーション番号のサイズ
    246         */
    247        public int getLocationSize() {
    248                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    249                if( location == null ) {
    250                        final String errMsg = "#makeFormat(DBTableModel)を先に実行しておいてください。" ;
    251                        throw new OgRuntimeException( errMsg );
    252                }
    253
    254                return location.length;
    255        }
    256
    257        /**
    258         * カラムのロケーション番号を返します。
    259         * 引数は、0 から、getLocationSize()-1 までの数で指定します。
    260         * 指定の位置の、フォーマットのカラム名に対応するロケーション番号
    261         * を返します。
    262         *
    263         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    264         *
    265         * @param no フォーム位置番号
    266         *
    267         * @return ロケーション番号
    268         */
    269        public int getLocation( final int no ) {
    270                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    271                if( location == null ) {
    272                        final String errMsg = "#makeFormat(DBTableModel)を先に実行しておいてください。" ;
    273                        throw new OgRuntimeException( errMsg );
    274                }
    275
    276                return location[no];
    277        }
    278
    279        /**
    280         * カラムのロケーション番号をIntStreamで返します。
    281         *
    282         * 指定の位置の、フォーマットのカラム名に対応するロケーション番号のIntStreamです。
    283         *
    284         * @og.rev 6.4.3.4 (2016/03/11) 内部のLocation配列を、IntStreamで返します。
    285         *
    286         * @return 内部のLocation配列を、IntStreamで返します。
    287         */
    288        public IntStream getLocationStream() {
    289                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    290                if( location == null ) {
    291                        final String errMsg = "#makeFormat(DBTableModel)を先に実行しておいてください。" ;
    292                        throw new OgRuntimeException( errMsg );
    293                }
    294
    295                return IntStream.of( location );
    296        }
    297
    298        /**
    299         * 指定のロケーション番号の値をクリアします。
    300         * ただし、直前のフォーマットに、td タグが存在する場合は、
    301         * style="display:none;" を設定することで、td タグそのものが
    302         * 無くなります。
    303         * その場合、段組みなどのレイアウトを行っていると、フォーマットが
    304         * 崩れますので、十分ご確認ください。
    305         * また、同一 td 内に複数のカラムを指定した場合は、tdタグ内のすべての
    306         * カラムが消えます。
    307         * td タグが存在しない場合は、非表示というより、データを空に
    308         * するだけになります。
    309         *
    310         * @og.rev 6.2.0.0 (2015/02/27) フォーマット系の noDisplay 対応
    311         * @og.rev 6.2.0.1 (2015/03/06) 非表示のマーカーに、Formatter#NO_DISPLAY を使用する。
    312         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    313         *
    314         * @param no フォーム位置番号
    315         */
    316        protected void setNoDisplay( final int no ) {
    317                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    318                if( location == null || format == null ) {
    319                        final String errMsg = "#makeFormat(DBTableModel)を先に実行しておいてください。" ;
    320                        throw new OgRuntimeException( errMsg );
    321                }
    322
    323                location[no] = Formatter.NO_DISPLAY ;
    324
    325                int tdIdx = format[no] == null ? -1 : format[no].indexOf( "<td" ) ;             // nullチェックも兼ねる
    326
    327                // 6.2.0.1 (2015/03/06) 非表示のマーカーの td に、style="display:none;" 追加
    328                if( tdIdx >= 0 ) {
    329                        int adrs = format[no].indexOf( "style=\"" );
    330                        if( adrs >= 0 ) {                                       // style 属性が既に存在する場合。
    331                                adrs += "style=\"".length();    // style=" の直後の位置を求める。
    332                                format[no] = format[no].substring( 0,adrs )
    333                                                                + "display:none;"
    334                                                                + format[no].substring( adrs ) ;
    335                        }
    336                        else {                                                          // style 属性がないので、td の直後に入れる。
    337                                tdIdx += "<td".length();                // td の直後の位置を求める。
    338                                format[no] = format[no].substring( 0,tdIdx )
    339                                                                + " style=\"display:none;\""
    340                                                                + format[no].substring( tdIdx ) ;
    341                        }
    342                }
    343        }
    344
    345        /**
    346         * フォーマット文字列を返します。
    347         * 引数は、0 から、getLocationSize() までの数で指定します。
    348         * 指定のフォーマットが、aaa[ABC]bbb[DEF]ccc[GHI]ddd となっている場合、
    349         * aaa , bbb , ccc , ddd を引数 0 , 1 , 2 , 3 で返します。
    350         *
    351         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    352         *
    353         * @param no フォーム位置番号
    354         *
    355         * @return フォーマット文字列
    356         */
    357        public String getFormat( final int no ) {
    358                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    359                if( format == null ) {
    360                        final String errMsg = "#makeFormat(DBTableModel)を先に実行しておいてください。" ;
    361                        throw new OgRuntimeException( errMsg );
    362                }
    363
    364                return format[no];
    365        }
    366
    367        /**
    368         * システムフォーマット文字列を返します。
    369         * システムフォーマット文字列は、[KEY.カラム名] などの特殊記号で指定された
    370         * カラム名の事で、location には、マイナスの値が設定されます。
    371         * マイナスの値に応じて、処理を変えることが出来ます。
    372         *
    373         * [KEY.カラム名] : 行番号付きカラム名
    374         * [I]            : 行番号
    375         * [J]            : 登録数         7.3.1.3 (2021/03/09) ※ ただし、ここでは登録件数が判らないため、行番号を返しておきます。
    376         * [ROW.ID]       : 行毎のチェックボックスのID
    377         * [ROW.JSON]     : 行毎の全データのJavaScriptオブジェクト形式
    378         *
    379         * @og.rev 3.5.5.0 (2004/03/12) [KEY.カラム名] 機能追加
    380         * @og.rev 3.5.5.2 (2004/04/02) [I] で、行番号を作成します。
    381         * @og.rev 3.6.0.0 (2004/09/17) [ROW.ID] で、行毎のチェックボックスのIDを返します。
    382         * @og.rev 4.0.0.0 (2007/05/02) Formatter を使用するように変更
    383         * @og.rev 6.2.0.1 (2015/03/06) 非表示のマーカーに、Formatter#NO_DISPLAY を使用する。
    384         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    385         * @og.rev 7.3.1.3 (2021/03/09) [J] で、登録件数(1～) を表現する。
    386         *
    387         * @param       row     行番号
    388         * @param       loc     位置番号
    389         *
    390         * @return フォーマット文字列
    391         * @og.rtnNotNull
    392         */
    393        public String getSystemFormat( final int row,final int loc ) {
    394//              if( loc == Formatter.SYS_ROWNUM ) {
    395                if( loc == Formatter.SYS_ROWNUM || loc == Formatter.SYS_CNT ) {
    396                        return String.valueOf( row );
    397                }
    398                else if( loc == Formatter.SYS_JSON ) {
    399                        // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    400                        if( formatter == null ) {
    401                                final String errMsg = "#makeFormat(DBTableModel)を先に実行しておいてください。" ;
    402                                throw new OgRuntimeException( errMsg );
    403                        }
    404
    405                        return formatter.getJson( row );
    406                }
    407                else if( loc == Formatter.NO_DISPLAY ) {                // 6.2.0.1 (2015/03/06) 非表示のマーカー
    408                        return "";
    409                }
    410
    411                final String errMsg = "システムフォーマットは、下記の形式しか使用できません。[" + loc + "]" + CR
    412                                + "  : [KEY.カラム名] : 行番号付きカラム名" + CR
    413                                + "  : [I]            : 行番号" + CR
    414                                + "  : [ROW.ID]       : 行毎のチェックボックスのID" + CR
    415                                + "  : [ROW.JSON]     : 行毎の全データのJavaScriptオブジェクト形式" ;
    416                throw new HybsSystemException( errMsg );
    417        }
    418
    419        /**
    420         * タイプ文字列を返します。
    421         * タイプとは、[XXX] の記述で、[#XXX] は、XXXカラムのラベルを、[$XXX]は、XXXカラムの
    422         * レンデラーを、[!XXX} は、値のみ取り出す指定を行います。
    423         * 主に、TextField系のフォーマットとTable系では、意味合いが異なりますので、
    424         * ご注意ください。
    425         *
    426         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    427         *
    428         * @param no フォーム位置番号
    429         *
    430         * @return タイプ文字列 '#':ラベルのみ  '$':レンデラー '!':値のみ  その他:通常
    431         */
    432        public char getType( final int no ) {
    433                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    434                if( type == null ) {
    435                        final String errMsg = "#makeFormat(DBTableModel)を先に実行しておいてください。" ;
    436                        throw new OgRuntimeException( errMsg );
    437                }
    438
    439                return type[no];
    440        }
    441
    442        /**
    443         * 設定された フォーマットの trタグを返します。
    444         * これは、trタグにclass属性他の設定がされていた場合に、変換後の
    445         * 文字列にも反映させる為に必要です。
    446         *
    447         * @og.rev 5.1.7.0 (2010/06/01) サニタイズ戻し処理("\\]\\"から"["に戻し)を追加
    448         *
    449         * @return フォーマットの trタグ
    450         * @og.rtnNotNull
    451         */
    452        public String getTrTag() {
    453                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
    454                return trTag == null ? "" : decodeSanitizedStr( trTag ) ;
    455        }
    456
    457        /**
    458         * カラムのクラス名(X,S9 など)のセットを行うかどうか指定します。
    459         *
    460         * "true" で、クラス属性を設定しません。これは、ＣＳＳファイルに書かれている属性を
    461         * 使用しないことを意味します。
    462         * 初期値は、"false" です。
    463         *
    464         * @param       flag クラス名使用の有無(true:使用しない/false:使用する。)
    465         */
    466        public void setNoClass( final String flag ) {
    467                noClass = StringUtil.nval( flag,noClass );
    468        }
    469
    470        /**
    471         * カラムのクラス名(X,S9 など)のセットを行うかどうか取得します。
    472         *
    473         * "true" で、クラス属性を設定しません。これは、ＣＳＳファイルに書かれている属性を
    474         * 使用しないことを意味します。
    475         * 初期値は、"false" です。
    476         *
    477         * @return      クラス名使用の有無(true:使用しない/false:使用する。)
    478         */
    479        public boolean isNoClass() {
    480                return noClass;
    481        }
    482
    483        /**
    484         * フォーマットの使用可否を判断するキーとなるカラム名を指定します。
    485         *
    486         * キーが、usableList に含まれる場合は、このフォームを使用できます。
    487         * キー(カラム名)が指定されない場合は、常に使用されます。
    488         * ※ 現時点では、BODYタイプのみ使用しています。
    489         *
    490         * @param  key フォーマットの使用可否を判断するカラム名
    491         */
    492        public void setUsableKey( final String key ) {
    493                usableKey = key;
    494        }
    495
    496        /**
    497         *  フォーマットの使用可否を判断する文字列リストを指定します。
    498         *
    499         * キーが、この文字列リスト中に存在する場合は、このフォームを使用できます。
    500         * この文字列リストは、固定な文字列です。{&#064;XXXX}は使用できますが、[XXXX]は
    501         * 使用できません。
    502         * 初期値は、"1" です。
    503         * ※ 現時点では、BODYタイプのみ使用しています。
    504         *
    505         * @param  list フォーマットの使用可否を判断する文字列リスト
    506         * @see TableFormatter#isUse( int,DBTableModel )
    507         */
    508        public void setUsableList( final String list ) {
    509                if( list != null ) {
    510                        usableList = list;
    511                }
    512        }
    513
    514        /**
    515         * ここで指定したカラムの値が、キーブレイクした場合、このタグを使用します。
    516         *
    517         * キーブレイクで 使用可否を指定する為の機能です。
    518         * この設定値は、usableKey,usableList とは、独立しているため、それぞれで
    519         * 有効になれば、使用されると判断されます。
    520         * キーブレイク判定では、最初の1件目は、必ず使用されると判断されます。
    521         *
    522         * @og.rev 5.7.6.3 (2014/05/23) 新規追加
    523         *
    524         * @param  kclm  キーブレイクをチェックするカラムID
    525         */
    526        public void setKeyBreakClm( final String kclm ) {
    527                keyBreakClm = kclm;
    528        }
    529
    530        /**
    531         * このフォーマットを使用するかどうかの問い合わせを返します。
    532         *
    533         * "true" で、使用します。setUsableKey( String ) で、指定された
    534         * カラム名の値が、setUsableList( String ) で指定された文字列に含まれていれば、
    535         * 使用します。カラム名がセットされない場合は、デフォルト値("true")が使用されます。
    536         * ※ 現時点では、BODYタイプのみ使用しています。
    537         * カラムのデータに、不正なスペースが入る場合を想定して、trim() しています。
    538         * よって、usableList の値にスペースは使用できません。
    539         *
    540         * 5.7.6.3 (2014/05/23) 以降は、keyBreakClm によるキーブレイクチェックも追加されました。
    541         * 従来の usableKey,usableList とは、独立しているため、それぞれで有効になれば、
    542         * 使用されると判断されます。
    543         *
    544         * @og.rev 3.5.6.2 (2004/07/05) 判定評価用カラムの値を trim() します。
    545         * @og.rev 5.7.6.3 (2014/05/23) キーブレイクをチェックする keyBreakClm 属性追加
    546         *
    547         * @param  row 行番号
    548         * @param       table   DBTableModelオブジェクト
    549         *
    550         * @return      このフォームを使用するかどうか(true:使用する/false:使用しない)
    551         * @see TableFormatter#setUsableKey( String )
    552         * @see TableFormatter#setUsableList( String )
    553         */
    554        public boolean isUse( final int row, final DBTableModel table ) {
    555
    556                // どちらも設定されていなければ、使用される(=true)
    557                if( usableKeyNo < 0 && breakClmNo < 0 ) { return true; }
    558
    559                // 以下、どちらかは設定されているため、true の時点で、使用される(=true)を返す。
    560                if( usableKeyNo >= 0 ) {
    561                        final String val = table.getValue( row,usableKeyNo ).trim();
    562                        if( usableList.indexOf( val ) >= 0 ) { return true; }
    563                }
    564
    565                if( breakClmNo >= 0 ) {
    566                        final String val = table.getValue( row,breakClmNo ).trim();
    567                        if( !val.equals( breakVal ) ) {                 // 同じでない場合は、true
    568                                breakVal = val;
    569                                return true;
    570                        }
    571                }
    572
    573                return false ;                  // 最後まで残ると、使用されないと判断、false を返す。
    574        }
    575
    576        /**
    577         *  itdフォーマット文字列を設定します。
    578         *
    579         * itd ボディ部の文字列を指定します。
    580         * itd ボディは、繰り返し処理を行います。これを、上位のボディ文字列の中の
    581         * HYBS_ITD_MARKER 文字列 と置き換えます。
    582         *
    583         * @og.rev 3.5.6.0 (2004/06/18) itdフォーマット文字列の取り込み
    584         *
    585         * @param  itd itdフォーマットの文字列
    586         */
    587        public void setItdBody( final String itd ) {
    588                if( itd != null ) {
    589                        itdBody = itd;
    590                }
    591        }
    592
    593        /**
    594         *  itdフォーマット文字列を取得します。
    595         *
    596         * itd ボディ部の文字列を取得します。
    597         * itd ボディは、繰り返し処理を行います。これを、上位のボディ文字列の中の
    598         * HYBS_ITD_MARKER 文字列 と置き換えます。
    599         *
    600         * @og.rev 3.5.6.0 (2004/06/18) itdフォーマット文字列の取り込み
    601         *
    602         * @return      itdフォーマットの文字列
    603         */
    604        public String getItdBody() {
    605                return itdBody;
    606        }
    607
    608        /**
    609         * サニタイズの戻し("\\]\\"から"["に戻し)を行います。
    610         *
    611         * @og.rev 5.1.7.0 (2010/06/01) 新規作成
    612         *
    613         * @param str サニタイズされた文字列
    614         *
    615         * @return サニタイズ戻し処理後の文字列
    616         */
    617        private String decodeSanitizedStr( final String str ) {
    618                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
    619                return str != null && str.indexOf( "\\]\\" ) >= 0 ?  str.replace( "\\]\\", "[" ) : str;
    620        }
    621}