    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.hayabusa.common.HybsSystem;
    019import org.opengion.fukurou.util.StringUtil;
    020import org.opengion.fukurou.util.XHTMLTag;
    021import org.opengion.hayabusa.html.AbstractViewForm;
    022import org.opengion.hayabusa.html.ViewCalendarParam;
    023
    024import java.util.Calendar;
    025
    026/**
    027 * １ヶ月分のカレンダー形式で、検索結果を表示する、カレンダー表示クラスです。
    028 *
    029 * AbstractViewForm により、setter/getterメソッドのデフォルト実装を提供しています。
    030 * 各HTMLのタグに必要な setter/getterメソッドのみ，追加定義しています。
    031 *
    032 * AbstractViewForm を継承している為,ロケールに応じたラベルを出力させる事が出来ます。
    033 *
    034 * @og.group 画面表示
    035 *
    036 * @version  4.0
    037 * @author   Kazuhiko Hasegawa
    038 * @since    JDK5.0,
    039 */
    040public class ViewForm_HTMLCalendar extends AbstractViewForm {
    041        //* このプログラムのVERSION文字列を設定します。   {@value} */
    042        private static final String VERSION = "5.1.6.0 (2010/05/01)" ;
    043
    044        private static final String[] WEEK_ja = { "日" ,"月" ,"火" ,"水" ,"木" ,"金" ,"土" ,"日" ,"月" };
    045        private static final String[] WEEK_en = { "SUN","MON","TUE","WED","THU","FRI","SAT","SUN","MON" };
    046        private static final String[] WEEK_MK = { "SUN","",   "",   "",   "",   "",   "SAT","SUN",""    };
    047
    048        private String[] week              ;
    049        private String[] viewKeys          ;            // カレンダを指定するキー配列        // 3.6.0.0 (2004/09/17)
    050        private String   ymKey             ;            // 年月のカラム名
    051        private String   dayKey            ;            // 休日(0:通常、1:休日)のカラム名
    052        private String   valKey            ;            // カレンダに表示する値のカラム名
    053        private boolean  valueBrFlag   ;                // 日付けと値の間に、BRタグを入れるかどうか
    054        private int              firstWeek         ;            // 曜日の開始(0:日曜 1:月曜)
    055        private int              columnSize        ;            // カレンダの横方向の繰り返し数       // 3.6.0.0 (2004/09/17)
    056
    057        /**
    058         * DBTableModel から HTML文字列を作成して返します。
    059         * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。
    060         * 表示残りデータが pageSize 以下の場合は,残りのデータをすべて出力します。
    061         *
    062         * @og.rev 3.5.2.1 (2003/10/27) 属性値の指定のシングルクオートをダブルクオートに変更。
    063         * @og.rev 3.6.0.0 (2004/09/17) 複数カレンダに対応
    064         * @og.rev 3.6.0.5 (2004/10/18) calenderParam の viewKeys バグ対応。
    065         * @og.rev 3.7.0.1 (2005/01/31) 全件チェックコントロール処理変更
    066         *
    067         * @param  startNo    表示開始位置
    068         * @param  pageSize   表示件数
    069         *
    070         * @return  DBTableModelから作成された HTML文字列
    071         */
    072        public String create( final int startNo, final int pageSize )  {
    073                if( getRowCount() == 0 ) { return ""; } // 暫定処置
    074
    075                paramInit();
    076
    077                int lastNo = getLastNo( startNo, pageSize );
    078
    079                StringBuilder out = new StringBuilder( HybsSystem.BUFFER_LARGE );
    080                out.append( "<table><tr>" ).append( HybsSystem.CR );
    081
    082                boolean onlyOne = ( lastNo - startNo ) == 1 ;   // 互換性のため、１件の処理のみ変更
    083
    084                // 3.7.0.1 (2005/01/31) 全件チェックコントロール処理変更
    085                if( ! onlyOne && isUseCheckControl() && "checkbox".equals( getSelectedType() ) ) {
    086                        out.append( "<tr><td>" ).append( getAllCheckControl() ).append( "</td></tr>");
    087                }
    088
    089                for( int row=startNo; row<lastNo; row++ ) {
    090                        out.append( "<td valign=\"top\">" );
    091
    092                        if( isWritable( row ) ) {
    093                                if( onlyOne ) {
    094                                        out.append( XHTMLTag.hidden( HybsSystem.ROW_SEL_KEY,String.valueOf( row ) ) );
    095                                        out.append( HybsSystem.CR );
    096                                }
    097                                else {
    098                                        out.append( "<input type=\"" ).append( getSelectedType() ).append( "\" " );
    099                                        out.append( "name=\"" ).append( HybsSystem.ROW_SEL_KEY ).append( "\" " );
    100                                        if( isChecked( row ) ) { out.append( " checked=\"checked\"" ); }
    101                                        out.append( "value=\"" ).append( row ).append( "\" />" );
    102                                }
    103                        }
    104
    105                        // 3.6.0.5 (2004/10/18)
    106                        for( int col = 0; col < viewKeys.length; col++ ) {
    107                                if( "_".equals( viewKeys[col] ) ) { continue; }
    108                                int newCol = getColumnNo( viewKeys[col] );
    109                                out.append("<span id=\"label\">");
    110                                out.append( getColumnLabel( newCol ) );
    111                                out.append( ":</span>" );
    112                                out.append( getValueLabel(row,newCol) );
    113                                out.append( "&nbsp;" );
    114                        }
    115                        out.append( HybsSystem.BR );
    116
    117                        out.append( makeCalendarData( row ) );
    118                        out.append( "</td>" );
    119                        if( (row+1) % columnSize == 0 ) {
    120                                out.append( "</tr><tr>" ).append( HybsSystem.CR );
    121                        }
    122                }
    123                out.append( "</tr></table>" ).append( HybsSystem.CR );
    124
    125                return out.toString();
    126        }
    127
    128        /**
    129         * DBTableModel の指定の行番号より、カレンダのHTML文字列を作成して返します。
    130         *
    131         * @og.rev 3.6.0.0 (2004/09/17) create( int startNo, int pageSize ) のロジックを移動
    132         * @og.rev 3.6.0.5 (2004/10/18) 印刷時の罫線出力関連機能の追加。id 属性を出力します。
    133         *
    134         * @param  row    指定の行番号
    135         *
    136         * @return  指定の行番号のカレンダのHTML文字列
    137         */
    138        private String makeCalendarData( final int row ) {
    139                String yyyymm = getValue( row,getColumnNo( ymKey ));
    140                Calendar currentCal = getCalendar( yyyymm );
    141
    142                StringBuilder out = new StringBuilder( HybsSystem.BUFFER_LARGE );
    143
    144                out.append( "<table id=\"viewCalendar\" border=\"0\" cellpadding=\"1\" cellspacing=\"2\">" ).append( HybsSystem.CR );   // 3.6.0.5 (2004/10/18)
    145                out.append( "  <tr><td class=\"titleStyle\" colspan=\"7\">" ).append( HybsSystem.CR );
    146                out.append( getValueLabel( row,getColumnNo( ymKey )) ).append( HybsSystem.CR );
    147                out.append( "  </td></tr>" ).append( HybsSystem.CR );
    148
    149                // 今月の最終日
    150                int daysInMonth = currentCal.getActualMaximum(Calendar.DAY_OF_MONTH);
    151                // カレンダーの週の初めを設定する。月曜開始のカレンダーを作成するときに利用
    152                currentCal.setFirstDayOfWeek( Calendar.SUNDAY + firstWeek );
    153
    154                // 週を表す番号  ０～６ の間
    155                int culDay = ( currentCal.get(Calendar.DAY_OF_WEEK)
    156                                                + ( 7 - currentCal.getFirstDayOfWeek() ) ) % 7 ;
    157
    158                // 曜日欄を記述します。
    159                out.append("  <tr>").append( HybsSystem.CR );
    160                for( int i=0; i<7; i++ ) {
    161                        out.append("    <td width=\"14%\" class=\"dayHead" );
    162                        out.append( WEEK_MK[i+firstWeek] ).append( "\">" );
    163                        out.append( week[i+firstWeek] ).append( "</td>" );
    164                        out.append( HybsSystem.CR );
    165                }
    166                out.append("  </tr>").append( HybsSystem.CR );
    167
    168                // 第一週の日付欄の空きスペースの計算
    169                if( culDay != 0 ) {
    170                        out.append("    <td colspan=\"" ).append( culDay ).append( "\">&nbsp;</td>" );
    171                }
    172
    173                // 日付欄を埋めます。
    174                String BR = valueBrFlag ? "<br />" : "" ;
    175                for(int day=1; day <= daysInMonth; day++) {
    176                        int    daycol = getColumnNo( dayKey + day );    // 動的日付けカラム番号取得
    177                        String daylbl = getValueLabel( row,daycol,day );        // ローカルの日付けラベルを求めるメソッド
    178                        String vallbl = "" ;
    179                        if( valKey != null ) {
    180                                int valcol = getColumnNo( valKey + day );       // 動的値カラム番号取得
    181                                vallbl = BR + getValueLabel( row,valcol );              // 通常の値をラベルを求めるメソッド
    182                        }
    183
    184                        if( "1".equals( getValue( row,daycol ))) {
    185                                out.append("    <td class=\"holyday\">" );
    186                                out.append( daylbl );
    187                                out.append( vallbl );
    188                                out.append("</td>");
    189                        } else {
    190                                out.append("    <td class=\"day" );
    191                                out.append( WEEK_MK[culDay+firstWeek] );
    192                                out.append("\">");
    193                                out.append( daylbl );
    194                                out.append( vallbl );
    195                                out.append("</td>");
    196                        }
    197                        out.append( HybsSystem.CR );
    198
    199                        // 週の終わりで、行を折り返す。
    200                        if( culDay == 6 ) {
    201                                out.append("  </tr>\n  <tr>").append( HybsSystem.CR );
    202                                culDay = 0;
    203                        } else {
    204                                culDay++;
    205                        }
    206                }
    207
    208                // 最終週の日付欄の空きスペースの計算
    209                if( (7-culDay) != 0 ) {
    210                        out.append("    <td colspan=\"" ).append( 7-culDay ).append( "\">&nbsp;</td>" );
    211                }
    212                out.append( HybsSystem.CR );
    213
    214                out.append( "</tr>" ).append( HybsSystem.CR );
    215                out.append( "</table>" ).append( HybsSystem.CR );
    216
    217                return out.toString();
    218        }
    219
    220        /**
    221         * このビーに対する特別な初期化を行う。
    222         *
    223         * @og.rev 3.5.4.0 (2003/11/25) TableFormatter クラスを使用するように変更。
    224         * @og.rev 3.5.5.9 (2004/06/07) ヘッダーの日付け表示に、Locale を加味できるように変更
    225         * @og.rev 3.6.0.0 (2004/09/17) viewKeys , columnSize 属性の追加
    226         *
    227         */
    228        private void paramInit() {
    229
    230                String viewKeysCd       = getParam( ViewCalendarParam.VIEW_KEYS                 ,ViewCalendarParam.VIEW_VALUES                  );      // 3.6.0.0 (2004/09/17)
    231                ymKey                           = getParam( ViewCalendarParam.YM_KEY                    ,ViewCalendarParam.YM_VALUE                             );
    232                dayKey                          = getParam( ViewCalendarParam.DAY_KEY                   ,ViewCalendarParam.DAY_VALUE                    );
    233                valKey                          = getParam( ViewCalendarParam.VALUE_KEY                 ,null                                                                   );
    234                String valueBrCd        = getParam( ViewCalendarParam.VALUE_BR_FLAG_KEY ,ViewCalendarParam.VALUE_BR_FLAG_VALUE  );
    235                String firstWeekCd      = getParam( ViewCalendarParam.FIRSTWEEK_KEY             ,ViewCalendarParam.FIRSTWEEK_VALUE              );
    236                String headerLocale     = getParam( ViewCalendarParam.HEADER_LOCALE_KEY ,ViewCalendarParam.HEADER_LOCALE_VALUE  );
    237                String columnSizeCd     = getParam( ViewCalendarParam.COLUMN_SIZE_KEY   ,ViewCalendarParam.COLUMN_SIZE_VALUE    );      // 3.6.0.0 (2004/09/17)
    238
    239                viewKeys    = StringUtil.csv2Array( viewKeysCd );
    240                firstWeek   = Integer.parseInt( firstWeekCd );
    241                valueBrFlag = Boolean.valueOf( valueBrCd ).booleanValue() ;
    242                columnSize  = Integer.parseInt( columnSizeCd );                 // 3.6.0.0 (2004/09/17)
    243
    244                // 曜日ヘッダーをコピーして作成します。
    245                if( "ja".equals( headerLocale ) ) {
    246                        week = WEEK_ja;
    247                }
    248                else {
    249                        week = WEEK_en;
    250                }
    251        }
    252
    253        /**
    254         * row行，colum列 のデータの値をHTML文字列に変換して返します。
    255         * リソースバンドルが登録されている場合は,リソースに応じた
    256         * HTML文字列を作成します。
    257         * カレンダーViewに特化した、ラベル値を返します。
    258         *
    259         * @og.rev 3.8.0.9 (2005/10/17) writableControl 追加による引数変更
    260         *
    261         * @param       row             行番号
    262         * @param       column  カラム番号
    263         * @param       day             日付
    264         *
    265         * @return      row行，colum列 のデータの値
    266         */
    267        private String getValueLabel( final int row, final int column, final int day ) {
    268                if( isColumnWritable( column ) && isWritable( row ) ) {
    269                        String val = getValue( row,column ) ;
    270                        return day + getEditorValue( row,column,val );
    271                }
    272                else {
    273                        return String.valueOf( day );
    274                }
    275        }
    276
    277        /**
    278         * 指定のYYYYMM文字列から、カレンダーオブジェクトを作成して返します。
    279         * 日にちは、１日にセットされます。
    280         *
    281         * @param   ym YYYYMM文字列
    282         *
    283         * @return  カレンダーオブジェクト
    284         */
    285        private Calendar getCalendar( final String ym ) {
    286                Calendar cal = Calendar.getInstance();
    287
    288                if( ym != null && ym.length() == 6 ) {
    289                        int yyyy = Integer.parseInt( ym.substring( 0,4 ) );
    290                        int mm   = Integer.parseInt( ym.substring( 4,6 ) ) - 1;
    291                        int dd   = 1;
    292                        cal.set( yyyy,mm,dd,0,0,0 );
    293                }
    294                else {
    295                        // カレンダーを今月の１日に設定する。
    296                        cal.set(Calendar.DAY_OF_MONTH, 1);
    297                }
    298
    299                return cal ;
    300        }
    301
    302        /**
    303         * フォーマットメソッドを使用できるかどうかを問い合わせます。
    304         *
    305         * @og.rev 3.6.0.0 (2004/09/17) 親クラス変更に伴なう、追加
    306         *
    307         * @return  使用可能(true)/ 使用不可能 (false)
    308         */
    309        public boolean canUseFormat() {
    310                return false;
    311        }
    312
    313        /**
    314         * 表示項目の編集(並び替え)が可能かどうかを返します
    315         *
    316         * @og.rev 5.1.6.0 (2010/05/01) 新規追加
    317         *
    318         * @return      表示項目の編集(並び替え)が可能かどうか(false:不可能)
    319         */
    320        @Override
    321        public boolean isEditable() {
    322                return false;
    323        }
    324}