    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 = "6.9.5.0 (2018/04/23)" ;
    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         *
    165         * @return      テーブルのタグ文字列
    166         * @og.rtnNotNull
    167         */
    168        @Override
    169        protected String getTableHead() {
    170                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    171                // 6.4.2.1 (2016/02/05) エラー判定を先に行う。
    172                if( clmNo == null ) {
    173                        final String errMsg = "#setColumnDisplay(String)を先に実行しておいてください。" ;
    174                        throw new HybsSystemException( errMsg );
    175                }
    176
    177                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    178
    179                // 5.7.5.0 (2014/04/04) HTML5 で colgroup が効かない対応
    180                // 本当は、tableタグの前に入れたかったが、ややこしいので table タグの直後に入れます。
    181                // 互換モードでない場合専用。処理速度を気にするより、処理を一か所にまとめておきます。
    182                // 6.9.5.0 (2018/04/23) USE_IE7_HEADER 廃止(false固定)
    183//              if( !useIE7Header ) {
    184                        buf.append( "<style type=\"text/css\">" ).append( CR );
    185                        int ad = 1;
    186                        if( isNumberDisplay() ) {
    187                                makeNthChild( buf,2,"BIT" );
    188                                makeNthChild( buf,3,"S9"  );
    189                                ad = 4;
    190                        }
    191
    192                        // 6.4.2.1 (2016/02/05) 変数名がややこしいので、変更しておきます。
    193                        // 5.9.14.3 (2016/11/25) editでの表示順変更に対応
    194        //              final int cnt = getColumnCount();
    195        //              for( int clm=0; clm<cnt; clm++ ) {
    196                        for( int clm=0; clm<clmCnt; clm++ ) { // 5.9.14.3 (2016/11/25) 表示順変更に対応していなかった
    197                                final int column = clmNo[clm];
    198                                if( isColumnDisplay( column ) ) {
    199                                        // 6.4.6.1 (2016/06/03) DbType とClassName が複雑化しているため、とりあえずの暫定対策。
    200                                        makeNthChild( buf,ad,getClassName(column) );            // 6.4.6.1 (2016/06/03)
    201                                        ad++ ;                  // tdタグの順番なので、表示する場合のみカウントする。
    202                                }
    203                        }
    204                        buf.append( "</style>" ).append( CR );
    205//              }
    206
    207                // 3.5.5.0 (2004/03/12) No 欄そのものの作成判断追加
    208                if( isNumberDisplay() ) {
    209                        // 5.9.1.2 (2015/10/23) 自己終了警告対応
    210                        // 6.4.4.1 (2016/03/18) NUMBER_DISPLAYを、static final 定数化します。
    211                        buf.append( NUMBER_DISPLAY );           // 6.8.1.0 (2017/07/14) HTML5ネイティブ時でも、出力します。
    212                }
    213
    214                // 5.1.6.0 (2010/05/01)
    215                for( int clm=0; clm<clmCnt; clm++ ) {
    216                        final int column = clmNo[clm];
    217                        if( isColumnDisplay( column ) ) {
    218                                buf.append("<colgroup class=\"" )
    219                                        .append( getClassName(column) )                 // 6.4.5.0 (2016/04/08)
    220                                        // 5.9.1.2 (2015/10/23) 自己終了警告対応
    221                                        .append("\"><!-- --></colgroup>")
    222                                        .append( CR );
    223                        }
    224                }
    225
    226        // 3.5.2.0 (2003/10/20) ヘッダー繰り返し部をgetHeadLine()へ移動
    227                buf.append("<thead id=\"header\">").append( CR )        // 3.5.6.5 (2004/08/09)
    228                        .append( getHeadLine() )
    229                        .append("</thead>").append( CR );
    230
    231                return buf.toString();
    232        }
    233
    234        /**
    235         * ヘッダー繰り返し部を、getTableHead()メソッドから分離。
    236         *
    237         * @og.rev 3.5.2.0 (2003/10/20) 新規作成
    238         * @og.rev 3.5.4.3 (2004/01/05) useCheckControl 属性の機能を追加
    239         * @og.rev 3.5.4.5 (2004/01/23) thタグの属性設定出来る様に新規追加。
    240         * @og.rev 3.5.4.6 (2004/01/30) numberType="none" 時の処理を追加(Noラベルを出さない)
    241         * @og.rev 3.5.4.7 (2004/02/06) ヘッダーにソート機能用のリンクを追加します。
    242         * @og.rev 3.7.0.1 (2005/01/31) 全件チェックコントロール処理変更
    243         * @og.rev 6.1.2.0 (2015/01/24) キャッシュを返すのを、#getHeadLine() に移動。
    244         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    245         * @og.rev 6.4.2.1 (2016/02/05) clmNo == null のエラー判定を先に行う。
    246         *
    247         * @param       thTag タグの文字列
    248         *
    249         * @return      テーブルのタグ文字列
    250         * @og.rtnNotNull
    251         */
    252        @Override
    253        protected String getHeadLine( final String thTag ) {
    254                // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
    255                // 6.4.2.1 (2016/02/05) エラー判定を先に行う。
    256                if( clmNo == null ) {
    257                        final String errMsg = "#setColumnDisplay(String)を先に実行しておいてください。" ;
    258                        throw new HybsSystemException( errMsg );
    259                }
    260
    261                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE )
    262                        .append("<tr class=\"row_hu\">").append( CR );
    263
    264                // 3.5.5.0 (2004/03/12) No 欄そのものの作成判断追加
    265                if( isNumberDisplay() ) {
    266                        // 3.5.4.3 (2004/01/05) 追加分
    267                        if( isUseCheckControl() && "checkbox".equals( getSelectedType() ) ) {
    268                                // 3.5.4.5 (2004/01/23) thタグの属性設定出来る様に変更。
    269                                // 6.0.2.5 (2014/10/31) char を append する。
    270                                buf.append( thTag ).append("></th>")
    271                                        .append( thTag ).append('>').append( getAllCheckControl() ).append("</th>")
    272                                        .append( thTag ).append('>').append( getNumberHeader()    ).append("</th>");    // 3.5.4.6 (2004/01/30)
    273                        }
    274                        else {
    275                                // 3.5.4.5 (2004/01/23) thタグの属性設定出来る様に変更。
    276                                buf.append( thTag ).append(" colspan='3'>").append( getNumberHeader() ).append("</th>");        // 3.5.4.6 (2004/01/30)
    277                        }
    278                }
    279                buf.append( CR );
    280
    281                // 5.1.6.0 (2010/05/01)
    282                for( int clm=0; clm<clmCnt; clm++ ) {
    283                        final int column = clmNo[clm];
    284                        if( isColumnDisplay( column ) ) {
    285                                // 3.5.4.5 (2004/01/23) thタグの属性設定出来る様に変更。
    286                                buf.append( thTag ).append('>')         // 6.0.2.5 (2014/10/31) char を append する。
    287                                        .append( getSortedColumnLabel(column) )
    288                                        .append("</th>").append( CR );
    289                        }
    290                }
    291                buf.append("</tr>").append( CR );
    292
    293                return buf.toString();                          // 6.1.2.0 (2015/01/24)
    294        }
    295
    296        /**
    297         * 表示可能カラム名を、CSV形式で与えます。
    298         * 例："OYA,KO,HJO,SU,DYSET,DYUPD"
    299         * setColumnDisplay( int column,boolean rw ) の簡易版です。
    300         * null を与えた場合は,なにもしません。
    301         *
    302         * @param       columnName      カラム名
    303         */
    304        @Override
    305        public void setColumnDisplay( final String columnName ) {
    306                super.setColumnDisplay( columnName );
    307
    308                if( columnName != null ) {
    309                        final String[] clmNames = StringUtil.csv2Array( columnName );
    310                        clmCnt = clmNames.length;
    311                        clmNo  = new int[clmCnt];
    312                        for( int i=0; i<clmCnt; i++ ) {
    313                                clmNo[i] = getColumnNo( clmNames[i] );
    314                        }
    315                }
    316                viewClms = columnName;
    317        }
    318
    319        /**
    320         * ビューで表示したカラムの一覧をCSV形式で返します。
    321         *
    322         * @og.rev 5.1.6.0 (2010/05/01) 新規追加
    323         * @og.rev 6.0.2.4 (2014/10/17) Edit機能で、オリジナルのカラム列を取得する必要がある。
    324         *
    325         * @return      ビューで表示したカラムの一覧
    326         */
    327        @Override
    328        public String getViewClms() {
    329                // 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)
    330                return viewClms == null ? super.getViewClms() : viewClms ;
    331        }
    332}