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