    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 java.util.List;
    019import java.util.ArrayList;
    020
    021import org.opengion.hayabusa.common.HybsSystem;
    022import org.opengion.hayabusa.common.HybsSystemException;
    023import org.opengion.hayabusa.html.ViewTimeTableParam;
    024
    025/**
    026 * 時間軸を持つタイムテーブルの表示を行うクラスです。
    027 *
    028 * パラメータが必要な場合は、ViewTimeTableParamTag を使用してください。
    029 *
    030 * パラメータが設定されていない場合は、ViewForm_HTMLTimeTable の初期値が使用されます。
    031 * (パラメータを使用するには、viewタグのuseParam 属性をtrueに設定する必要があります。)
    032 *
    033 * SELECT文は、日付、キー、備考、開始時刻、終了時刻、リンクが、必須項目で、この並び順は、
    034 * 完全に固定です。よって、カラム位置を指定する必要はありませんが、SELECT文を自由に
    035 * 設定することも出来ませんので、ご注意ください。
    036 * この固定化に伴い、WRITABLE 指定も使用できません。
    037 * なお、日付、キー、備考 に関しては、columnDisplay 属性で、表示の ON/OFF 制御は可能です。
    038 * また、日付ブレイク、キーブレイクの設定で、カラム自体をテーブルの外に出すことが可能です。
    039 * (キーと備考はセットになっています。)
    040 *
    041 * タイムテーブルが空きの場合のリンクを指定できます。(ViewTimeTableParam.NULL_LINK_CLM_ID)
    042 * (ViewTimeTableParam の nullLinkColumn 属性)
    043 * 指定しない場合は、空きのリンクは作成されません。
    044 * このリンクは、特殊で、引数に、パラメータを追加できますが、"($1)"、"($2)" で指定します。
    045 * この($1)、($2)は、開始時刻、終了時刻がセットされますが、SELECT文の固定カラムと同じ
    046 * 並び順ですが、DBTableModelの値を設定しているわけではありません。
    047 * 空きの場合は、データ自体が存在しない場合と、日付、キー のみが 外部結合で生成された
    048 * レコードが実際に存在する場合がありますが、外部結合で生成されたレコードには、
    049 * 開始時刻、終了時刻はありません。($1) と($2)には、それぞれ、最小開始時刻と最大終了時刻を
    050 * セットします。
    051 *
    052 * 例として、&amp;TMSTART=($1)&amp;TMEND=($2) という文字列の ($*) 部分を解析して割当ます。
    053 *
    054 * ブレーク処理を行うカラムＩＤをCSV形式でセットできます。(ViewTimeTableParam.BREAK_CLMS)
    055 * (ViewTimeTableParam の breakClms 属性)
    056 * これは、ブレイク毎にテーブルが分かれて、テーブルの先頭に、ブレイクした
    057 * 値が表示されます。
    058 * 例えば、日付カラムをブレイクカラムとして設定すると、日付がブレイクするたび、
    059 * 日付をヘッダーに出して、テーブルを作成します。
    060 * ブレークカラムは、CSV形式で複数指定できます。その場合は、複数指定のカラムの
    061 * 合成された値で、キーブレイクの判定を行います。(簡単に言うとＯＲ判定になります。)
    062 * なお、ブレイクカラムを指定した場合は、自動的に、noDisplay 属性にその値をセット
    063 * します。
    064 *
    065 * @og.rev 5.4.0.0 (2011/10/01) 新規追加
    066 * @og.group 画面表示
    067 *
    068 * @version  4.0
    069 * @author       Kazuhiko Hasegawa
    070 * @since    JDK5.0,
    071 */
    072public class ViewForm_HTMLTimeTable extends ViewForm_HTMLTable {
    073        //* このプログラムのVERSION文字列を設定します。   {@value} */
    074        private static final String VERSION = "5.4.4.2 (2012/02/03)" ;
    075
    076//      private int             intval          = 5;                    // 30分=5 単位に colspan を設定する。
    077//      private int             minStTime       = 80;                   // 08:00 のこと。30分=5 換算
    078//      private int             maxEdTime       = 210;                  // 21:00 のこと。
    079        private int             intval          = 30;                   // 30分 単位に colspan を設定する。
    080        private int             minStTime       = 480;                  // 08:00 のこと。8H=480M
    081        private int             maxEdTime       = 1260;                 // 21:00 のこと。21H=1260M
    082
    083        private static final int        dyClmNo         = 0;    // ヘッダー1：ただし、グループ化する場合は、外出し
    084        private static final int        keyClmNo        = 1;    // ヘッダー2：ただし、グループ化する場合は、外出し
    085        private static final int        bikoClmNo       = 2;    // ヘッダー3：(内部では使用していません。)
    086
    087        private static final int        tmstClmNo       = 3;    // 時間枠の開始時刻(含む)
    088        private static final int        tmedClmNo       = 4;    // 時間枠の終了時刻(含まない)
    089        private static final int        linkClmNo       = 5;    // 時間枠に表示する予約情報(変更画面へのリンク)
    090
    091        private static final int        clmCnt          = 3;    // 決め打ち。今は、dyClm,keyClm の２つだけ表示
    092
    093        // 引数に、DYUSE=(dyClm)&UNITID=(keyClm)&TMSTART=(stTime)&TMEND=(edTime) を追加する。
    094//      private String  linkValue       = "<a href=\"../GK0101/index.jsp?command=NEW&NORESERVE="
    095//                                                                      + "&DYUSE=($1)&UNITID=($2)&TMSTART=($3)&TMEND=($4)"
    096//                                                                      + "&BACK_GAMENID=GK0000&GAMENID=GK0101&BACK_ADDRESS=/gk/jsp/GK0000/index.jsp\" target=\"CONTENTS\">"
    097//                                                                      + "<img src=\"../customImage/gk/space.gif\" width=\"100%\" height=\"20px\" />"
    098//                                                                      + "</a>" ;
    099        // 引数パース機能付き データが存在しない場合のリンクのベースを設定。
    100//      private String  linkValue               = "" ;          // null にするとエラーになるので、空文字列
    101        private int             nullLinkClmNo   = -1 ;          // 固定ではなく可変の場合に利用するリンクカラムNo
    102
    103        private int             tdClassColumnNo = -1 ;          // 5.4.3.7 (2012/01/20) データを入れるTDタグにclass属性を付与する場合のカラムNo
    104
    105//      private int[]   breakClmNos             = null;         // ブレーク処理を行うカラムNo
    106        private boolean isDyBreak               = true;         // 日付でブレイクするかどうかを指定
    107        private boolean isBookingMerge  = false;        // 5.4.4.2 (2012/02/03) ブッキングデータをマージするかどうかを指定
    108
    109        /**
    110         * 内容をクリア(初期化)します。
    111         *
    112         * @og.rev 5.4.3.7 (2012/01/20) tdClassColumnNo 追加
    113         * @og.rev 5.4.4.2 (2012/02/03) isBookingMerge 追加
    114         *
    115         */
    116        @Override
    117        public void clear() {
    118                super.clear();
    119
    120//              intval          = 5;                    // 30分=5 単位に colspan を設定する。
    121//              minStTime       = 80;                   // 08:00 のこと。30分=5 換算
    122//              maxEdTime       = 210;                  // 21:00 のこと。
    123                intval          = 30;                   // 30分 単位に colspan を設定する。
    124                minStTime       = 480;                  // 08:00 のこと。8H=480M
    125                maxEdTime       = 1260;                 // 21:00 のこと。21H=1260M
    126
    127//              linkValue               = "" ;                  // null にするとエラーになるので、空文字列
    128                nullLinkClmNo   = -1;                   // 固定ではなく可変の場合に利用するリンクカラム
    129//              breakClmNos             = null;                 // ブレーク処理を行うカラムNo
    130                tdClassColumnNo = -1 ;                  // 5.4.3.7 (2012/01/20) データを入れるTDタグにclass属性を付与する場合のカラムNo
    131                isDyBreak               = true;                 // 日付でブレイクするかどうかを指定
    132                isBookingMerge  = false;                // 5.4.4.2 (2012/02/03) ブッキングデータをマージするかどうかを指定
    133        }
    134
    135        /**
    136         * DBTableModel から HTML文字列を作成して返します。
    137         * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。
    138         * 表示残りデータが pageSize 以下の場合は,残りのデータをすべて出力します。
    139         *
    140         * @og.rev 5.4.3.7 (2012/01/20) tdClassColumnNo 追加
    141         * @og.rev 5.4.4.2 (2012/02/03) isBookingMerge 追加
    142         *
    143         * @param  startNo        表示開始位置
    144         * @param  pageSize   表示件数
    145         *
    146         * @return      DBTableModelから作成された HTML文字列
    147         */
    148        @Override
    149        public String create( final int startNo, final int pageSize )  {
    150                if( getRowCount() == 0 ) { return ""; } // 暫定処置
    151
    152                paramInit();
    153                headerLine       = null;
    154                int lastNo = getLastNo( startNo, pageSize );
    155                int hsc = getHeaderSkipCount();
    156                int hscCnt = 1;
    157
    158                StringBuilder out = new StringBuilder( HybsSystem.BUFFER_LARGE );
    159
    160                if( isDyBreak ) {
    161                        out.append( getRendererValue( 0,dyClmNo ) ).append( HybsSystem.CR );
    162                        setColumnDisplay( dyClmNo,false );      // 日付ブレイクなら、setColumnDisplay をfalse にセット
    163                }
    164
    165                out.append( getHeader() );
    166
    167                out.append("<tbody>").append( HybsSystem.CR );
    168                int bgClrCnt = 0;
    169
    170                int maxColspan = (maxEdTime-minStTime)/intval ;         // この数が、TDの数になる。
    171                int rowColspan = 0;                                                                     // 5.5.0.3(2012/03/12) １行の累積TD数。最大は、maxColspan で、
    172                int stTime     = minStTime;
    173
    174                String backData    = "";        // 初期値。１回目にキーブレイクさせる。
    175
    176                List<String> dblBooking = new ArrayList<String>();          // 重複データがあったときのデータ格納
    177                String nlVal     = null;                // 空リンクのベース値
    178                String tdCls     = null;                // 5.4.3.7 (2012/01/20) tdClassColumnNo 追加
    179                String dyVal     = null;                // 日付項目の値
    180                String keyVal    = null;                // キー項目の値
    181//              String breakVal  = null;                // キーブレイクの値
    182                String bk_nlVal  = null;                // キーブレイク時の元の空リンクのベース値
    183                String bk_dyVal  = "";                  // キーブレイク時の元の日付
    184//              String bk_breakVal = "";                // キーブレイクの元の値
    185                for( int row=startNo; row<lastNo; row++ ) {
    186                        // キーブレイクの判定
    187                        bk_nlVal   = nlVal;
    188//                      bk_dyVal   = dyVal;
    189//                      bk_keyVal  = keyVal;
    190
    191//                      nlVal = (nullLinkClmNo < 0 ) ? linkValue : getRendererValue( row,nullLinkClmNo );
    192                        nlVal = (nullLinkClmNo < 0 ) ? null : getRendererValue( row,nullLinkClmNo );
    193                        tdCls = (tdClassColumnNo < 0 ) ? null : getValue( row,tdClassColumnNo );     // 5.4.3.7 (2012/01/20)
    194                        dyVal   = getValue( row,dyClmNo );
    195                        keyVal  = getValue( row,keyClmNo );
    196                        if( row==startNo ) { bk_dyVal   = dyVal; }              // 初期データをセット。
    197                        //
    198//                      if( breakClmNos != null ) {
    199//                              StringBuilder blkVal = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    200//                              for( int i=0; i<breakClmNos.length; i++ ) {
    201//                                      blkVal.append( getValue( row,breakClmNos[i] ) );
    202//                              }
    203//                              breakVal = blkVal.toString();
    204//                      }
    205
    206                        String linkVal = getRendererValue( row,linkClmNo );
    207
    208                        // キーブレイク判定。キーブレイクは、一番初めから来る。
    209                        if( !backData.equals( dyVal + keyVal ) ) {
    210                                backData   = dyVal + keyVal;                    // null は来ないはず
    211
    212                                // minStTime < stTime の時だけ、処理を行う。(最初のキーブレイクは処理しないため)
    213                                if( minStTime < stTime ) {
    214                                        // まずは、前の td の残りを出力する。ここでは、キーブレイク前の値を使用する。
    215                                        if( stTime < maxEdTime ) {
    216                                                out.append("  ");               // td タグの出力前の段落
    217                                                // 残データの書き出しは、最大TD数-それまでにセットした数。
    218                                                int td = maxColspan - rowColspan;               // 5.5.0.3(2012/03/12)
    219//                                              appendTag( out , "td" , (maxEdTime-stTime)/intval ,
    220//                                              appendTDTag( out , null , (maxEdTime-stTime)/intval ,   // 5.4.3.7 (2012/01/20)
    221                                                appendTDTag( out , null , td ,  // 5.5.0.3(2012/03/12)
    222                                                                                makeLinkValue( bk_nlVal , stTime , maxEdTime ) );
    223//                                                                              makeLinkValue( bk_nlVal , bk_dyVal , bk_keyVal , stTime , maxEdTime ) );
    224                                        }
    225                                        out.append("</tr>").append( HybsSystem.CR );
    226                                }
    227                                stTime = minStTime;             // 初期化
    228
    229                                // データかぶりが発生したときの処理
    230                                if( !dblBooking.isEmpty() ) {
    231                                        for( String bkdt : dblBooking ) {
    232                                                out.append("<tr").append( getBgColorCycleClass( bgClrCnt-1 ) ).append(">").append( HybsSystem.CR );
    233                                                out.append( bkdt );
    234                                                out.append("</tr>").append( HybsSystem.CR );
    235                                        }
    236                                        dblBooking.clear();
    237                                }
    238
    239                                // 日付ブレイク処理
    240                                if( isDyBreak && row > startNo && !bk_dyVal.equals( dyVal ) ) {
    241                                        bk_dyVal = dyVal;
    242                                        out.append("<tr class=\"dummy\">");
    243                                        for(int column = 0; column < clmCnt; column++) {
    244                                                if( isColumnDisplay( column ) ) {
    245                                                        out.append("<td/>");
    246                                                }
    247                                        }
    248//                                      for( int i=0; i<(maxEdTime-minStTime)/intval ; i++ ) {
    249                                        for( int i=0; i<maxColspan ; i++ ) {         // 5.5.0.3(2012/03/12) 空td の出力。TD の colspan の基準になる。
    250                                                out.append("<td/>");
    251                                        }
    252                                        out.append("</tr>").append( HybsSystem.CR );
    253                                        out.append("</tbody>").append( HybsSystem.CR );
    254                                        out.append("</table>").append( HybsSystem.CR );
    255
    256                                        out.append( getRendererValue( row,dyClmNo ) ).append( HybsSystem.CR );
    257
    258                                        out.append( getHeader() );
    259                                        out.append("<tbody>").append( HybsSystem.CR );
    260                                        hscCnt = 1;
    261                                }
    262
    263                                // ヘッダー繰り返し属性( headerSkipCount )を採用
    264                                if( hsc > 0 && hscCnt % hsc == 0 ) {
    265                                        out.append( getHeadLine() );
    266                                        hscCnt = 1;
    267                                }
    268                                else {
    269                                        // 特殊処理：ここの処理では、一番最初も、実行されるので、＋＋しないように加工しておく。
    270                                        if( row > startNo ) { hscCnt ++ ; }
    271                                }
    272
    273                                // ここから、新しい行が始まる。
    274                                out.append("<tr").append( getBgColorCycleClass( bgClrCnt++ ) ).append(">").append( HybsSystem.CR );
    275                                rowColspan = 0 ;                // 5.5.0.3(2012/03/12) 初期化
    276
    277                                for(int column = 0; column < clmCnt; column++) {
    278                                        if( isColumnDisplay( column ) ) {
    279                                                // ヘッダー部分に加工しやすいように、class 属性を与えておく。
    280                                                out.append("  <td class=\"" ).append( getColumnName( column ) ).append( "\">" );
    281                                                out.append( getValueLabel(row,column) );
    282                                                out.append("</td>").append( HybsSystem.CR );
    283                                        }
    284                                }
    285                        }
    286
    287                        // 文字列型の時分情報を数字に変換する。
    288//                      int clStTime = getStr2Time( getValue( row,tmstClmNo ) , minStTime );
    289                        int clStTime = getStr2Time( getValue( row,tmstClmNo ) , -1 );
    290                        boolean nullData = (clStTime < 0) ;  // 開始時刻が        null の場合、-1 が返されるのでフラグをセットする。
    291                        if( clStTime < minStTime ) { clStTime = minStTime; } // 最小値以下の場合は、最小値に合せる。
    292
    293                        int clEdTime = getStr2Time( getValue( row,tmedClmNo ) , maxEdTime );
    294                        if( clEdTime > maxEdTime ) { clEdTime = maxEdTime; } // 最大値以上の場合は、最大値に合せる。
    295
    296                        if( clStTime == clEdTime ) { clEdTime = clEdTime + intval ; }   // 最初と最後が同じ場合は、intval分 進めておく。
    297
    298                        // 最初と最後が異なる場合は、間に空欄が入る。同じ場合は、連続なので、空欄は入らない。
    299                        if( stTime < clStTime ) {
    300                                out.append("  ");               // td タグの出力前の段落
    301
    302                                // 5.5.0.3(2012/03/12) 間に空欄が入る場合、その大きさが最小TD単位より大きければ、分割する。
    303                                // ただし、直前の TD 個数が、最小でない場合のみ。
    304                                int td = (clStTime-stTime)/intval;              // 5.5.0.3(2012/03/12)
    305                                rowColspan += td;
    306//                              appendTag( out , "td" , (clStTime-stTime)/intval ,
    307//                              appendTDTag( out , null , (clStTime-stTime)/intval ,            // 5.4.3.7 (2012/01/20)
    308                                appendTDTag( out , null , td ,          // 5.5.0.3(2012/03/12)
    309                                                                                makeLinkValue( nlVal , stTime , clStTime ) ).append( HybsSystem.CR );
    310//                                                                              makeLinkValue( nlVal , dyVal , keyVal , stTime , clStTime ) ).append( HybsSystem.CR );
    311                        }
    312                        // 前のデータとかぶっている。つまり、ブッキングデータがある。
    313                        else if( stTime > clStTime ) {
    314                                // 5.4.4.2 (2012/02/03) ブッキングデータをマージする機能を追加
    315                                if( isBookingMerge ) {
    316                                        if( stTime < clEdTime ) {
    317                                                int td = (clEdTime-stTime)/intval;              // 5.5.0.3(2012/03/12)
    318                                                rowColspan += td ;
    319//                                              appendTDTag( out , tdCls , (clEdTime-stTime)/intval , linkVal ).append( HybsSystem.CR );
    320                                                appendTDTag( out , tdCls , td , linkVal ).append( HybsSystem.CR );
    321                                                stTime = clEdTime;
    322                                        }
    323                                        continue;
    324                                }
    325
    326                                StringBuilder buf2 = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    327
    328                                buf2.append("  ");              // td タグの出力前の段落
    329//                              appendTag( buf2 , "td" , clmCnt );                                                                      // ヘッダー部分
    330                                for(int column = 0; column < clmCnt; column++) {
    331                                        if( isColumnDisplay( column ) ) {
    332                                                // ヘッダー部分に加工しやすいように、class 属性を与えておく。
    333                                                buf2.append("<td class=\"" ).append( getColumnName( column ) ).append( "\"/>" );
    334                                        }
    335                                }
    336
    337//                              appendTag( buf2 , "td" , (clStTime-minStTime)/intval );                         // 最初からデータまで
    338//                              appendTag( buf2 , "td" , (clEdTime-clStTime)/intval , linkVal );        // データ部
    339//                              appendTag( buf2 , "td" , (maxEdTime-clEdTime)/intval );                         // データから最後まで
    340
    341                                // 5.4.3.7 (2012/01/20)
    342                                appendTDTag( buf2 , null  , (clStTime-minStTime)/intval );                              // 最初からデータまで
    343                                appendTDTag( buf2 , tdCls , (clEdTime-clStTime)/intval , linkVal );             // データ部: 5.4.3.7 (2012/01/20) td に class属性追加
    344                                appendTDTag( buf2 , null  , (maxEdTime-clEdTime)/intval );                              // データから最後まで
    345
    346                                dblBooking.add( buf2.toString() );
    347                                continue;
    348                        }
    349                        // 前も後ろも最小と最大になっているのは、予約レコードが無いため。
    350//                      else if( clStTime == minStTime && clEdTime == maxEdTime ) {
    351                        // stTime == clStTime のケース。nullData = true で、予約レコードが無いため。
    352                        else if( nullData ) {
    353//                              linkVal = makeLinkValue( nlVal , dyVal , keyVal , minStTime , maxEdTime );
    354                                linkVal = makeLinkValue( nlVal , minStTime , maxEdTime );
    355                        }
    356                        // 5.4.3.7 (2012/01/20) linkVal を共通に使用している箇所を修正
    357
    358                        out.append("  ");               // td タグの出力前の段落
    359//                      appendTag( out , "td" , (clEdTime-clStTime)/intval , linkVal ).append( HybsSystem.CR );
    360                        int td = (clEdTime-clStTime)/intval;            // 5.5.0.3(2012/03/12)
    361                        rowColspan += td ;
    362//                      appendTDTag( out , tdCls , (clEdTime-clStTime)/intval , linkVal ).append( HybsSystem.CR );      // 5.4.3.7 (2012/01/20) td に class属性追加
    363                        appendTDTag( out , tdCls , td , linkVal ).append( HybsSystem.CR );      // 5.5.0.3(2012/03/12)
    364
    365                        stTime = clEdTime ;
    366                }
    367
    368                // 残処理：データが残っている場合は、書き出す必要がある。
    369                if( ( minStTime < stTime && stTime < maxEdTime ) ) {
    370                        out.append("  ");               // td タグの出力前の段落
    371//                      appendTag( out , "td" , (maxEdTime-stTime)/intval ,
    372                        // 残データの書き出しは、最大TD数-それまでにセットした数。
    373                        int td = maxColspan - rowColspan;               // 5.5.0.3(2012/03/12)
    374//                      appendTDTag( out , null , (maxEdTime-stTime)/intval ,           // 5.4.3.7 (2012/01/20)
    375                        appendTDTag( out , null , td ,          // 5.5.0.3(2012/03/12)
    376                                                                                makeLinkValue( nlVal , stTime , maxEdTime ) );
    377//                                                                              makeLinkValue( nlVal , dyVal , keyVal , stTime , maxEdTime ) );
    378//                      out.append("</tr>").append( HybsSystem.CR );
    379
    380                        // データかぶりが発生したときの処理
    381//                      if( !dblBooking.isEmpty() ) {
    382//                              for( String bkdt : dblBooking ) {
    383//                                      out.append("<tr").append( getBgColorCycleClass( bgClrCnt-1 ) ).append(">").append( HybsSystem.CR );
    384//                                      out.append( bkdt );
    385//                                      out.append("</tr>").append( HybsSystem.CR );
    386//                              }
    387//                      }
    388//              }
    389//              else {
    390//                      out.append("</tr>").append( HybsSystem.CR );
    391                }
    392                out.append("</tr>").append( HybsSystem.CR );
    393
    394                // データかぶりが発生したときの処理
    395                if( !dblBooking.isEmpty() ) {
    396                        for( String bkdt : dblBooking ) {
    397                                out.append("<tr").append( getBgColorCycleClass( bgClrCnt-1 ) ).append(">").append( HybsSystem.CR );
    398                                out.append( bkdt );
    399                                out.append("</tr>").append( HybsSystem.CR );
    400                        }
    401                }
    402
    403                // カラムの結合があるため、td タグを個別に出力しておかないと、レイアウトがずれる。
    404                out.append("<tr class=\"dummy\">");
    405                for(int column = 0; column < clmCnt; column++) {
    406                        if( isColumnDisplay( column ) ) {
    407                                out.append("<td/>");
    408                        }
    409                }
    410//              for( int i=0; i<(maxEdTime-minStTime)/intval ; i++ ) {
    411                for( int i=0; i<maxColspan ; i++ ) {         // 5.5.0.3(2012/03/12) 空td の出力。TD の colspan の基準になる。
    412                        out.append("<td/>");
    413                }
    414                out.append("</tr>").append( HybsSystem.CR );
    415
    416                out.append("</tbody>").append( HybsSystem.CR );
    417                out.append("</table>").append( HybsSystem.CR );
    418
    419                out.append( getScrollBarEndDiv() );     // 3.8.0.3 (2005/07/15)
    420                return out.toString();
    421        }
    422
    423        /**
    424         * パラメータ内容を初期化します。
    425         *
    426         * @og.rev 5.4.3.7 (2012/01/20) tdClassColumnNo 追加。intval の実値化
    427         * @og.rev 5.4.4.2 (2012/02/03) isBookingMerge 追加
    428         *
    429         */
    430        private void paramInit() {
    431                String s_intval         = getParam( ViewTimeTableParam.TIME_INTERVAL    , null );
    432                String s_minStTime      = getParam( ViewTimeTableParam.MIN_START_TIME   , null );
    433                String s_maxEdTime      = getParam( ViewTimeTableParam.MAX_END_TIME             , null );
    434
    435//              String[] s_brkClms      = StringUtil.csv2Array( getParam( ViewTimeTableParam.BREAK_CLMS , null ) );
    436
    437                isDyBreak               = Boolean.valueOf( getParam( ViewTimeTableParam.USE_DY_BREAK, "true" ) );
    438
    439                // 5.4.4.2 (2012/02/03) ブッキングデータをマージするかどうかを指定
    440                isBookingMerge  = Boolean.valueOf( getParam( ViewTimeTableParam.USE_BOOKING_MERGE, "false" ) );
    441
    442                // nullリンクのカラム名指定。nullClm が優先順位が高い。
    443                String s_nullClm        = getParam( ViewTimeTableParam.NULL_LINK_CLM_ID , null );
    444                if( s_nullClm != null ) {
    445                        nullLinkClmNo = getColumnNo( s_nullClm );
    446                }
    447//              else {
    448//                      linkValue       = getParam( ViewTimeTableParam.BODY_LINK_VALUE  , linkValue );
    449//              }
    450
    451                // 5.4.3.7 (2012/01/20) データを入れるTDタグにclass属性を付与する場合のカラムNo
    452                String s_tdClsClm       = getParam( ViewTimeTableParam.TD_CLASS_COLUMN_ID       , null );
    453                if( s_tdClsClm != null ) {
    454                        tdClassColumnNo = getColumnNo( s_tdClsClm );
    455                }
    456
    457                // BREAK_CLMS は、csv2Array しているので、null は来ない。
    458//              if( s_brkClms.length > 0 ) {
    459//                      breakClmNos     = new int[s_brkClms.length];
    460//                      for( int i=0; i<s_brkClms.length; i++ ) {
    461//                              breakClmNos[i] = getColumnNo( s_brkClms[i] );
    462//                      }
    463//              }
    464
    465                if( s_intval != null ) {
    466                        intval = Integer.parseInt( s_intval ) ; // 5.4.3.7 (2012/01/20)
    467                }
    468//              intval          = getStr2Time( s_intval         , intval );                             // インターバル。0030 なら、5。  30分=5 換算
    469                minStTime       = getStr2Time( s_minStTime      , minStTime );                  // 最小開始時刻。0800 なら、80。 30分=5 換算
    470                maxEdTime       = getStr2Time( s_maxEdTime      , maxEdTime );                  // 最大終了時刻。2100 なら、210。30分=5 換算
    471        }
    472
    473        /**
    474         * DBTableModel から テーブルのタグ文字列を作成して返します。
    475         *
    476         * @og.rev 5.4.3.7 (2012/01/20) colgroup は不要
    477         *
    478         * @return      テーブルのタグ文字列
    479         */
    480        @Override
    481        protected String getTableHead() {
    482                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    483
    484        //  5.4.3.7 (2012/01/20) colgroup は不要
    485        //      for(int column = 0; column < clmCnt; column++) {
    486        //              if( isColumnDisplay( column ) ) {
    487        //                      buf.append("<colgroup class=\"" );
    488        //                      buf.append( getColumnDbType(column) );          // 4.0.0 (2005/01/31)
    489        //                      buf.append("\"/>");
    490        //                      buf.append( HybsSystem.CR );
    491        //              }
    492        //      }
    493
    494                // 3.5.2.0 (2003/10/20) ヘッダー繰り返し部をgetHeadLine()へ移動
    495                buf.append("<thead id=\"header\">").append( HybsSystem.CR );      // 3.5.6.5 (2004/08/09)
    496                buf.append( getHeadLine() );
    497                buf.append("</thead>").append( HybsSystem.CR );
    498
    499                return buf.toString();
    500        }
    501
    502        /**
    503         * ヘッダー繰り返し部を、getTableHead()メソッドから分離。
    504         *
    505         * @param       thTag タグの文字列
    506         *
    507         * @return      テーブルのタグ文字列
    508         */
    509        @Override
    510        protected String getHeadLine( final String thTag ) {
    511                if( headerLine != null ) { return headerLine; }         // キャッシュを返す。
    512
    513                StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    514
    515                buf.append("<tr class=\"row_h\"").append(" >").append( HybsSystem.CR );
    516
    517                buf.append( HybsSystem.CR );
    518                for(int column = 0; column < clmCnt; column++) {
    519                        if( isColumnDisplay( column ) ) {
    520//                              buf.append( thTag ).append(">");
    521                                buf.append( thTag ).append(" class=\"" ).append( getColumnName( column ) ).append( "\">" );
    522                                buf.append( getColumnLabel(column) );
    523                                buf.append("</th>").append( HybsSystem.CR );
    524                        }
    525                }
    526
    527//              for(int tm = minStTime; tm < maxEdTime; tm+=10 ) {   // intval づつ進めるべきだが、1時間ごとの箱とする。
    528                for(int tm = minStTime; tm < maxEdTime; tm+=60 ) {   // ヘッダーは、１時間単位とする。
    529//                      buf.append( thTag ).append(" class=\"timeVar\" colspan=\"2\">");
    530                        buf.append( thTag ).append(" class=\"timeVar\" colspan=\"" ).append( 60/intval ).append( "\">");
    531//                      buf.append( (tm/10) );
    532                        buf.append( (tm/60) );
    533                        buf.append("</th>").append( HybsSystem.CR );
    534                }
    535
    536                buf.append("</tr>").append( HybsSystem.CR );
    537
    538                headerLine = buf.toString();
    539                return headerLine;
    540        }
    541
    542        /**
    543         * TDタグ文字列を簡易的に合成します。
    544         *
    545         * ここでは、主に、class 属性、colspan 属性を設定することを目的にしています。
    546         * colspan の値によって、動作を変化させています。
    547         *   0: タグそのものを生成しません。これは、第一引数をそのまま返します。
    548         *   1: colspan 属性を出力しません。(Default値なので)
    549         *   それ以外は、colspan に引数を設定します。
    550         * BODY 部も、無指定の場合は、/&gt; 止めのタグを出力します。
    551         *
    552         * 返り値の StringBuilder は、第一引数そのものを返します。よって、このメソッドに、
    553         * append を連結していくことも可能です。
    554         * (return値を使わなくても、第一引数の StringBuilder は変化しています。副作用というやつ。)
    555         *
    556         * @og.rev 5.4.3.7 (2012/01/20) tdタグ専用に変更。
    557         *
    558         * @param       buf             このStringBuilderに append します。
    559         * @param       cls             追加する class 属性
    560         * @param       colspan td , th タグ属性に追加する colspan値。
    561         *                     0 の場合は、タグ自体を出力しません。
    562         *                     1 の場合は、colspan を出力しません。
    563         * @param       body    タグの BODY 部に出力する内容(String可変長引数)０件の場合は、BODYなし
    564         *
    565         * @return      appendされたStringBuilder(第一引数と同じオブジェクト)
    566         */
    567//      private StringBuilder appendTag( final StringBuilder buf , final String tag , final int colspan , final String... body ) {
    568        private StringBuilder appendTDTag( final StringBuilder buf , final String cls , final int colspan , final String... body ) {
    569                if( colspan == 0 ) { return buf; }
    570
    571//              buf.append( "<" ).append( tag );
    572//              if( colspan > 1 ) {
    573//                      buf.append( " colspan=\"" ).append( colspan ).append( "\"" );
    574//              }
    575//
    576//              int cnt = body.length;
    577//              if( cnt == 0 ) { buf.append( " />" ); }
    578//              else {
    579//                       buf.append( ">" );
    580//                      for( int i=0; i<cnt; i++ ) {
    581//                              buf.append( body[i] );
    582//                      }
    583//                       buf.append( "</" ).append( tag ).append( ">" );
    584//              }
    585
    586                buf.append( "<td" );
    587                // class 属性の追加
    588                if( cls != null && !cls.isEmpty() ) {
    589                        buf.append( " class=\"" ).append( cls ).append( "\"" );
    590                }
    591
    592                // colspan 属性の追加
    593                if( colspan > 1 ) {
    594                        buf.append( " colspan=\"" ).append( colspan ).append( "\"" );
    595                }
    596
    597                int cnt = body.length;
    598                if( cnt == 0 ) { buf.append( " />" ); }
    599                else {
    600                         buf.append( ">" );
    601                        for( int i=0; i<cnt; i++ ) {
    602                                buf.append( body[i] );
    603                        }
    604                         buf.append( "</td>" );
    605                }
    606
    607                return buf;
    608        }
    609
    610        /**
    611         * 時間文字列を数字に変換します。
    612         *
    613         * "0800" は、480に、"2100" は、1260 に変換します。
    614         *
    615         * @og.rev 5.4.3.7 (2012/01/20) 計算方法の変更
    616         *
    617         * @param       val     時間文字列の値(0800 など)
    618         * @param       defTm   引数の時間文字列が null の場合の初期値
    619         *
    620         * @return      時間文字列を数字に変換した結果( 80 など)
    621         */
    622        private int getStr2Time( final String val , final int defTm ) {
    623                if( val == null || val.isEmpty() ) { return defTm; }
    624                else if( val.length() != 4 ) {
    625                        String errMsg = "時間引数は、４桁必要です。" +
    626                                                        "  val=[" + val + "]";
    627                        throw new HybsSystemException( errMsg );
    628                }
    629
    630//              return Integer.parseInt( val.substring( 0,2 ) )*10 +
    631//                                      Integer.parseInt( val.substring( 2 ) )/6 ;      // 30分=5 になるように
    632                return Integer.parseInt( val.substring( 0,2 ) )*60 +
    633                                        Integer.parseInt( val.substring( 2 ) ) ;        // 5.4.3.7 (2012/01/20)
    634
    635        }
    636
    637        /**
    638         * 数字を時間文字列に変換します。
    639         *
    640         * 480は、"0800" に、"1260"は、2100 に変換します。
    641         *
    642         * @og.rev 5.4.3.7 (2012/01/20) 計算方法の変更
    643         *
    644         * @param       timeVal 引数の時間文字列が null の場合の初期値
    645         *
    646         * @return      数字を時間文字列に変換した結果( "0800" など)
    647         */
    648        private String getInt2StrTime( final int timeVal ) {
    649                int tmpVal = timeVal;
    650                if(      tmpVal < minStTime ) { tmpVal = minStTime; }        // 最小値以下の場合は、最小値に合せる
    651                else if( tmpVal > maxEdTime ) { tmpVal = maxEdTime; }        // 最大値以上の場合は、最大値に合せる。
    652
    653                //        桁合せ    85→8→800 の変換         85→5→30 の変換      足して、10830 になる。
    654//              int rtn = 10000 + ( tmpVal / 10 ) * 100 + ( ( tmpVal % 10 ) * 6 ) ;
    655
    656//              return String.valueOf( rtn ).substring(1);                      // "0830" 部分を返す。
    657                return String.valueOf(100+ tmpVal/60).substring(1) + String.valueOf(100+tmpVal%60).substring(1);
    658        }
    659
    660        // 引数に、 を追加する。
    661
    662        /**
    663         * リンク文字列をパースします。
    664         *
    665         * データの空欄にリンクを作成するときに、元となるリンク文字列の引数を設定します。
    666         * 引数は、&TMSTART=(stTime)&TMEND=(edTime) を追加するイメージです。
    667         * stTime、edTime は、それぞれ、($1)、($2) の変数が割り当てられます。
    668         * stTime、edTime は、#getInt2StrTime( int ) メソッドで変換した文字列を利用します。
    669         *
    670         * @param       lnkVal  リンクのベースとなる値
    671         * @param       stTime  開始時刻の数字表記
    672         * @param       edTime  終了時刻の数字表記
    673         *
    674         * @return      リンク文字列をパースした結果
    675         */
    676        private String makeLinkValue( final String lnkVal,final int stTime,final int edTime ) {
    677//      private String makeLinkValue( final String lnkVal,final String dyClm,final String keyClm,final int stTime,final int edTime ) {
    678                String rtn = "";
    679                if( lnkVal != null ) {
    680        //              rtn = lnkVal.replace( "($1)",getInt2StrTime( stTime ) )
    681        //                                              .replace( "($2)",getInt2StrTime( edTime ) ) ;
    682//                                                      .replace( "($3)",dyClm )
    683//                                                      .replace( "($4)",keyClm ) ;
    684
    685                        // URLエンコードがかかっている場合。なお、分解して処理しないのは、他にURLエンコードされている箇所を考慮して。
    686                        rtn = lnkVal.replace( "%28%241%29",getInt2StrTime( stTime ) )
    687                                                        .replace( "%28%242%29",getInt2StrTime( edTime ) ) ;
    688//                                                      .replace(  "%28%243%29",dyClm )
    689//                                                      .replace( "%28%244%29",keyClm ) ;
    690                }
    691
    692                return rtn;
    693        }
    694
    695        /**
    696         * 表示項目の編集(並び替え)が可能かどうかを返します
    697         *
    698         * @return      表示項目の編集(並び替え)が可能かどうか(false:不可能)
    699         */
    700        @Override
    701        public boolean isEditable() {
    702                return false;
    703        }
    704}