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 * 1ヶ月分のカレンダー形式で、検索結果を表示する、カレンダー表示クラスです。 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 ; // 互換性のため、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( " " ); 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 // 週を表す番号 0~6 の間 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( "\"> </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( "\"> </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 * 日にちは、1日にセットされます。 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 // カレンダーを今月の1日に設定する。 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}