    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.view;
    017
    018import org.opengion.fukurou.util.StringUtil;
    019import org.opengion.hayabusa.common.HybsSystemException;
    020
    021/**
    022 * 検索結果を自動的に表形式に変換する、テーブル作成クラスです。
    023 *
    024 * ユーザー単位に表示するカラムの順番、表示可非を指定できるように対応します。
    025 * setColumnDisplay( final String columnName ) に、指定された順番に
    026 * 表示するというHTMLFormatTable の簡易版として用意します。
    027 * 各HTMLのタグに必要な setter/getterメソッドのみ，追加定義しています。
    028 *
    029 * AbstractViewForm を継承している為,ロケールに応じたラベルを出力させる事が出来ます。
    030 *
    031 * @og.group 画面表示
    032 * @og.rev 5.1.6.0 (2010/05/01) 新規作成
    033 *
    034 * @version  4.0
    035 * @author       Kazuhiko Hasegawa
    036 * @since    JDK5.0,
    037 */
    038public class ViewForm_HTMLSeqClmTable extends ViewForm_HTMLTable {
    039        /** このプログラムのVERSION文字列を設定します。   {@value} */
    040        private static final String VERSION = "7.0.4.0 (2019/05/31)" ;
    041
    042        private int[]   clmNo           ;               // 5.1.6.0 (2010/05/01)
    043        private int             clmCnt          = -1;   // 5.1.6.0 (2010/05/01)
    044
    045        private String  viewClms        ;
    046
    047        /**
    048         * デフォルトコンストラクター
    049         *
    050         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    051         */
    052        public ViewForm_HTMLSeqClmTable() { super(); }          // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    053
    054        /**
    055         * DBTableModel から HTML文字列を作成して返します。
    056         * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。
    057         * 表示残りデータが pageSize 以下の場合は,残りのデータをすべて出力します。
    058         *
    059         * @og.rev 5.5.4.2 (2012/07/13) editName指定時の編集対応
    060         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    061         * @og.rev 6.4.2.1 (2016/02/05) clmNo == null のエラー判定を先に行う。
    062         * @og.rev 6.8.1.1 (2017/07/22) ckboxTD変数は、&lt;td&gt; から &lt;td に変更します(タグの最後が記述されていない状態でもらう)。
    063         *
    064         * @param  startNo        表示開始位置
    065         * @param  pageSize   表示件数
    066         *
    067         * @return      DBTableModelから作成された HTML文字列
    068         * @og.rtnNotNull
    069         */
    070        @Override
    071        public String create( final int startNo, final int pageSize )  {
    072                if( getRowCount() == 0 ) { return ""; } // 暫定処置
    073
    074                // 6.4.2.1 (2016/02/05) エラー判定を先に行う。
    075                if( clmNo == null ) {
    076                        final String errMsg = "#setColumnDisplay(String)を先に実行しておいてください。" ;
    077                        throw new HybsSystemException( errMsg );
    078                }
    079
    080                headerLine       = null;
    081
    082                final StringBuilder out = new StringBuilder( BUFFER_LARGE )
    083                        .append( getCountForm( startNo,pageSize ) )
    084                        .append( getHeader() )
    085                        .append("<tbody>").append( CR );                // 6.4.1.1 (2016/01/16) PMD refactoring.
    086
    087                int bgClrCnt = 0;
    088                // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid declaring a variable if it is unreferenced before a possible exit point.
    089                final String ckboxTD = "  <td";                                 // 6.8.1.1 (2017/07/22)
    090                final int lastNo = getLastNo( startNo, pageSize );
    091                final int blc = getBackLinkCount();
    092                final int hsc = getHeaderSkipCount();                   // 3.5.2.0 (2003/10/20)
    093                int hscCnt   = 1;                                                               // 3.5.2.0 (2003/10/20)
    094                for( int row=startNo; row<lastNo; row++ ) {
    095                        if( isSkip( row ) || isSkipNoEdit( row ) ) { continue; } // 4.3.1.0 (2008/09/08)
    096                        out.append(" <tr").append( getBgColorCycleClass( bgClrCnt++,row ) );
    097                        if( isNoTransition() ) {        // 4.3.3.0 (2008/10/01)
    098                                out.append( getHiddenRowValue( row ) );
    099                        }
    100                        out.append('>').append( CR );                           // 6.0.2.5 (2014/10/31) char を append する。
    101
    102                        // 3.5.5.0 (2004/03/12) No 欄そのものの作成判断追加
    103                        if( isNumberDisplay() ) {
    104                                out.append( makeCheckbox( ckboxTD, row, blc ) ).append( CR );
    105                        }
    106
    107                        // 5.1.6.0 (2010/05/01)
    108                        for( int clm=0; clm<clmCnt; clm++ ) {
    109                                final int column = clmNo[clm];
    110                                if( isColumnDisplay( column ) ) {
    111                                        out.append("  <td>")
    112                                                .append( getValueLabel(row,column) )
    113                                                .append("</td>").append( CR );
    114                                }
    115                        }
    116
    117                        // 5.5.4.2 (2012/07/13) mustとmuntAnyでwritableのものはdisplay:noneで出力する(可能な限り余分なものは出力しない)
    118                        for( int column=0; column<clmCnt; column++ ) {
    119                                if( !isColumnDisplay( column ) && ( isMustColumn( column ) || isMustAnyColumn(column) ) && isColumnWritable( column) ) {
    120                                        out.append("  <td style=\"display:none\">")
    121                                                .append( getValueLabel(row,column) )
    122                                                .append("</td>").append( CR );
    123                                }
    124                        }
    125
    126                        out.append(" </tr>").append( CR );
    127
    128                        // 3.5.2.0 (2003/10/20) ヘッダー繰り返し属性( headerSkipCount )を採用
    129                        if( hsc > 0 && hscCnt % hsc == 0 ) {
    130                                out.append( getHeadLine() );
    131                                hscCnt = 1;
    132                        }
    133                        else {
    134                                hscCnt ++ ;
    135                        }
    136                }
    137                out.append("</tbody>").append( CR )
    138                        .append("</table>").append( CR )
    139                        .append( getScrollBarEndDiv() );        // 3.8.0.3 (2005/07/15)
    140
    141                return out.toString();
    142        }
    143
    144        /**
    145         * DBTableModel から テーブルのタグ文字列を作成して返します。
    146         *
    147         * @og.rev 3.5.1.0 (2003/10/03) Noカラムに、numberType 属性を追加
    148         * @og.rev 3.5.2.0 (2003/10/20) ヘッダー繰り返し部をgetHeadLine()へ移動
    149         * @og.rev 3.5.3.1 (2003/10/31) VERCHAR2 を VARCHAR2 に修正。
    150         * @og.rev 3.5.5.0 (2004/03/12) No 欄そのものの作成判断ロジックを追加
    151         * @og.rev 3.5.6.5 (2004/08/09) thead に、id="header" を追加
    152         * @og.rev 4.0.0.0 (2005/01/31) DBColumn の 属性(CLS_NM)から、DBTYPEに変更
    153         * @og.rev 4.0.0.0 (2005/01/31) 新規作成(getColumnClassName ⇒ getColumnDbType)
    154         * @og.rev 6.1.2.0 (2015/01/24) HTML5 で colgroup が効かない対応
    155         * @og.rev 5.9.1.2 (2015/10/23) 自己終了警告対応
    156         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    157         * @og.rev 6.4.2.1 (2016/02/05) clmNo == null のエラー判定を先に行う。
    158         * @og.rev 6.4.4.1 (2016/03/18) NUMBER_DISPLAYを、static final 定数化します。
    159         * @og.rev 6.4.5.0 (2016/04/08) メソッド変更( getColumnDbType(int) → getClassName(int) )
    160         * @og.rev 6.4.6.1 (2016/06/03) DbType とClassName が複雑化しているため、とりあえずの暫定対策。
    161         * @og.rev 5.9.14.3 (2016/11/25) editでの表示順変更に対応
    162         * @og.rev 6.8.1.0 (2017/07/14) HTML5対応ヘッダー出力設定時に、ブラウザを互換設定したときの対応。
    163         * @og.rev 6.9.5.0 (2018/04/23) USE_IE7_HEADER 廃止(false固定)
    164         * @og.rev 7.0.4.0 (2019/05/31) colgroup 廃止
    165         *
    166         * @return      テーブルのタグ文字列
    167         * @og.rtnNotNull
    168         */
    169        @Override
    170        protected String getTableHead() {
    171                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    172                // 6.4.2.1 (2016/02/05) エラー判定を先に行う。
    173                if( clmNo == null ) {
    174                        final String errMsg = "#setColumnDisplay(String)を先に実行しておいてください。" ;
    175                        throw new HybsSystemException( errMsg );
    176                }
    177
    178                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    179
    180                // 5.7.5.0 (2014/04/04) HTML5 で colgroup が効かない対応
    181                // 本当は、tableタグの前に入れたかったが、ややこしいので table タグの直後に入れます。
    182                // 互換モードでない場合専用。処理速度を気にするより、処理を一か所にまとめておきます。
    183                // 6.9.5.0 (2018/04/23) USE_IE7_HEADER 廃止(false固定)
    184//              if( !useIE7Header ) {
    185                        buf.append( "<style type=\"text/css\">" ).append( CR );
    186                        int ad = 1;
    187                        if( isNumberDisplay() ) {
    188                                makeNthChild( buf,2,"BIT" );
    189                                makeNthChild( buf,3,"S9"  );
    190                                ad = 4;
    191                        }
    192
    193                        // 6.4.2.1 (2016/02/05) 変数名がややこしいので、変更しておきます。
    194                        // 5.9.14.3 (2016/11/25) editでの表示順変更に対応
    195        //              final int cnt = getColumnCount();
    196        //              for( int clm=0; clm<cnt; clm++ ) {
    197                        for( int clm=0; clm<clmCnt; clm++ ) { // 5.9.14.3 (2016/11/25) 表示順変更に対応していなかった
    198                                final int column = clmNo[clm];
    199                                if( isColumnDisplay( column ) ) {
    200                                        // 6.4.6.1 (2016/06/03) DbType とClassName が複雑化しているため、とりあえずの暫定対策。
    201                                        makeNthChild( buf,ad,getClassName(column) );            // 6.4.6.1 (2016/06/03)
    202                                        ad++ ;                  // tdタグの順番なので、表示する場合のみカウントする。
    203                                }
    204                        }
    205                        buf.append( "</style>" ).append( CR );
    206//              }
    207
    208//              // 3.5.5.0 (2004/03/12) No 欄そのものの作成判断追加
    209//              // 7.0.4.0 (2019/05/31) colgroup 廃止
    210//              if( isNumberDisplay() ) {
    211//                      // 5.9.1.2 (2015/10/23) 自己終了警告対応
    212//                      // 6.4.4.1 (2016/03/18) NUMBER_DISPLAYを、static final 定数化します。
    213//                      buf.append( NUMBER_DISPLAY );           // 6.8.1.0 (2017/07/14) HTML5ネイティブ時でも、出力します。
    214//              }
    215
    216                // 5.1.6.0 (2010/05/01)
    217                // 7.0.4.0 (2019/05/31) colgroup 廃止
    218//              for( int clm=0; clm<clmCnt; clm++ ) {
    219//                      final int column = clmNo[clm];
    220//                      if( isColumnDisplay( column ) ) {
    221//                              buf.append("<colgroup class=\"" )
    222//                                      .append( getClassName(column) )                 // 6.4.5.0 (2016/04/08)
    223//                                      // 5.9.1.2 (2015/10/23) 自己終了警告対応
    224//                                      .append("\"><!-- --></colgroup>")
    225//                                      .append( CR );
    226//                      }
    227//              }
    228
    229        // 3.5.2.0 (2003/10/20) ヘッダー繰り返し部をgetHeadLine()へ移動
    230                buf.append("<thead id=\"header\">").append( CR )        // 3.5.6.5 (2004/08/09)
    231                        .append( getHeadLine() )
    232                        .append("</thead>").append( CR );
    233
    234                return buf.toString();
    235        }
    236
    237        /**
    238         * ヘッダー繰り返し部を、getTableHead()メソッドから分離。
    239         *
    240         * @og.rev 3.5.2.0 (2003/10/20) 新規作成
    241         * @og.rev 3.5.4.3 (2004/01/05) useCheckControl 属性の機能を追加
    242         * @og.rev 3.5.4.5 (2004/01/23) thタグの属性設定出来る様に新規追加。
    243         * @og.rev 3.5.4.6 (2004/01/30) numberType="none" 時の処理を追加(Noラベルを出さない)
    244         * @og.rev 3.5.4.7 (2004/02/06) ヘッダーにソート機能用のリンクを追加します。
    245         * @og.rev 3.7.0.1 (2005/01/31) 全件チェックコントロール処理変更
    246         * @og.rev 6.1.2.0 (2015/01/24) キャッシュを返すのを、#getHeadLine() に移動。
    247         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    248         * @og.rev 6.4.2.1 (2016/02/05) clmNo == null のエラー判定を先に行う。
    249         *
    250         * @param       thTag タグの文字列
    251         *
    252         * @return      テーブルのタグ文字列
    253         * @og.rtnNotNull
    254         */
    255        @Override
    256        protected String getHeadLine( final String thTag ) {
    257                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    258                // 6.4.2.1 (2016/02/05) エラー判定を先に行う。
    259                if( clmNo == null ) {
    260                        final String errMsg = "#setColumnDisplay(String)を先に実行しておいてください。" ;
    261                        throw new HybsSystemException( errMsg );
    262                }
    263
    264                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
    265                        .append("<tr class=\"row_hu\">").append( CR );
    266
    267                // 3.5.5.0 (2004/03/12) No 欄そのものの作成判断追加
    268                if( isNumberDisplay() ) {
    269                        // 3.5.4.3 (2004/01/05) 追加分
    270                        if( isUseCheckControl() && "checkbox".equals( getSelectedType() ) ) {
    271                                // 3.5.4.5 (2004/01/23) thタグの属性設定出来る様に変更。
    272                                // 6.0.2.5 (2014/10/31) char を append する。
    273                                buf.append( thTag ).append("></th>")
    274                                        .append( thTag ).append('>').append( getAllCheckControl() ).append("</th>")
    275                                        .append( thTag ).append('>').append( getNumberHeader()    ).append("</th>");    // 3.5.4.6 (2004/01/30)
    276                        }
    277                        else {
    278                                // 3.5.4.5 (2004/01/23) thタグの属性設定出来る様に変更。
    279                                buf.append( thTag ).append(" colspan='3'>").append( getNumberHeader() ).append("</th>");        // 3.5.4.6 (2004/01/30)
    280                        }
    281                }
    282                buf.append( CR );
    283
    284                // 5.1.6.0 (2010/05/01)
    285                for( int clm=0; clm<clmCnt; clm++ ) {
    286                        final int column = clmNo[clm];
    287                        if( isColumnDisplay( column ) ) {
    288                                // 3.5.4.5 (2004/01/23) thタグの属性設定出来る様に変更。
    289                                buf.append( thTag ).append('>')         // 6.0.2.5 (2014/10/31) char を append する。
    290                                        .append( getSortedColumnLabel(column) )
    291                                        .append("</th>").append( CR );
    292                        }
    293                }
    294                buf.append("</tr>").append( CR );
    295
    296                return buf.toString();                          // 6.1.2.0 (2015/01/24)
    297        }
    298
    299        /**
    300         * 表示可能カラム名を、CSV形式で与えます。
    301         * 例："OYA,KO,HJO,SU,DYSET,DYUPD"
    302         * setColumnDisplay( int column,boolean rw ) の簡易版です。
    303         * null を与えた場合は,なにもしません。
    304         *
    305         * @param       columnName      カラム名
    306         */
    307        @Override
    308        public void setColumnDisplay( final String columnName ) {
    309                super.setColumnDisplay( columnName );
    310
    311                if( columnName != null ) {
    312                        final String[] clmNames = StringUtil.csv2Array( columnName );
    313                        clmCnt = clmNames.length;
    314                        clmNo  = new int[clmCnt];
    315                        for( int i=0; i<clmCnt; i++ ) {
    316                                clmNo[i] = getColumnNo( clmNames[i] );
    317                        }
    318                }
    319                viewClms = columnName;
    320        }
    321
    322        /**
    323         * ビューで表示したカラムの一覧をCSV形式で返します。
    324         *
    325         * @og.rev 5.1.6.0 (2010/05/01) 新規追加
    326         * @og.rev 6.0.2.4 (2014/10/17) Edit機能で、オリジナルのカラム列を取得する必要がある。
    327         *
    328         * @return      ビューで表示したカラムの一覧
    329         */
    330        @Override
    331        public String getViewClms() {
    332                // 6.3.9.1 (2015/11/27) A method should have only one exit point, and that should be the last statement in the method.(PMD)
    333                return viewClms == null ? super.getViewClms() : viewClms ;
    334        }
    335}