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.hayabusa.db; 017 018import java.util.Calendar; 019 020import org.opengion.hayabusa.common.HybsSystem; 021import org.opengion.fukurou.util.LogWriter; 022 023/** 024 * データのコード情報を取り扱うクラスです。 025 * 026 * 開始、終了、ステップの情報から、HTMLのメニューやリストを作成するための オプション 027 * タグを作成したり、与えられたキーをもとに、チェック済みのオプションタグを作成したりします。 028 * 029 * ここでは、時間(時:分)の自動生成を行います。パラメータで、開始、終了、ステップ、開始前設定値、終了後設定値 030 * を指定できます。 031 * キーは、4文字の HHMM 形式で与えられます。ラベルは、HH:MM になります。 032 * ステップは、分単位です。つまり、1時間の場合は、"60" と指定します。"0100"ではありません。 033 * 開始前設定値、終了後設定値はそれぞれ、開始の前と終了の後ろに特別に値を設定できます。 034 * 035 * 開始、または、終了に、現在時刻からの相対値を指定する事ができます。 036 * H1 ~ HXXX とすれば、現在時刻の時に数字部分を+-します。分は0に初期化されます。 037 * 038 * パラメータの初期値は、開始(0700)、終了(1900)、ステップ(30)、開始前設定値(null)、終了後設定値(null) です。 039 * 040 * 例:0800,2000,30 → 0800,0830,0900,0930,1000,・・・1900,1930,2000 のプルダウン 041 * 例:0800,2000,30,0000:△,2400:▽ → 0000,0800,0830,0900,0930,1000,・・・1900,1930,2000,2400 のプルダウン 042 * 043 * @og.group 選択データ制御 044 * @og.rev 5.6.1.1 (2013/02/08) 新規追加 045 * 046 * @version 4.0 047 * @author Kazuhiko Hasegawa 048 * @since JDK5.0, 049 */ 050// public class Selection_HM implements Selection { 051public class Selection_HM extends Selection_NULL { 052 private final String CACHE ; 053 private final String ST_ED_STEP ; 054 055 private final long maxCacheTime ; // キャッシュの破棄タイミングを計るための最大有効時間 056 057 /** 058 * コンストラクター 059 * 060 * 引数は、開始、終了、ステップ、開始前設定値、終了後設定値 です。 061 * パラメータの初期値は、開始(0700)、終了(1900)、ステップ(30)、開始前設定値(null)、終了後設定値(null) です。 062 * 063 * @param editPrm 開始、終了、ステップ、開始前設定値、終了後設定値 を表す引数(例:0800,2000,30) 064 */ 065 public Selection_HM( final String editPrm ) { 066 // if( param.length < 3 ) { 067 // String errMsg = "引数は、開始、終了、ステップ、[開始前設定値]、[終了後設定値]です。最低でも3個必要です。"; 068 // throw new IllegalArgumentException( errMsg ); 069 // } 070 071 String[] param = (editPrm == null) ? new String[0] : editPrm.split( "," ) ; 072 073 String start = (param.length > 0) ? param[0].trim() : "0700" ; 074 String end = (param.length > 1) ? param[1].trim() : "1900" ; 075 String step = (param.length > 2) ? param[2].trim() : "30" ; 076 077 String stOp = (param.length > 3) ? param[3].trim() : null ; 078 String enOp = (param.length > 4) ? param[4].trim() : null ; 079 080 int stepTime = Integer.parseInt( step ); 081 if( stepTime == 0 ) { 082 String errMsg = "ステップ に 0 は指定できません。無限ループします。"; 083 throw new IllegalArgumentException( errMsg ); 084 } 085 086 Calendar cal = Calendar.getInstance(); 087 calendarCalc( cal, start ); 088 089 Calendar endCal = Calendar.getInstance(); 090 calendarCalc( endCal, end ); 091 092 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 093 094 addOption( buf,stOp ); // 開始前設定値 の追加 095 096 // cal.before( endCal ) では、同一時刻の場合に false になる為、ここの判定では使えません。 097 // sign を掛け算しているのは、逆順対応 098 int sign = ( stepTime > 0 ) ? 1 : -1 ; // ステップの符号。 099 while( endCal.compareTo( cal ) * sign >= 0 ) { 100 int hh = cal.get( Calendar.HOUR_OF_DAY ); // 時 101 int mm = cal.get( Calendar.MINUTE ); // 分 102 103 String hVal = (hh < 10) ? "0" + hh : String.valueOf( hh ) ; 104 String mVal = (mm < 10) ? "0" + mm : String.valueOf( mm ) ; 105 106 buf.append( "<option value=\"" ).append( hVal ).append( mVal ).append( "\"" ); 107 buf.append( ">" ).append( hVal ).append( ":" ).append( mVal ).append( "</option>" ); 108 109 cal.add( Calendar.MINUTE,stepTime ); // 時刻に加えるのは、分 110 } 111 112 addOption( buf,enOp ); // 終了後設定値 の追加 113 114 CACHE = buf.toString(); 115 ST_ED_STEP = "Start=" + start + " , End=" + end + " , Step=" + step + " , StartBefore=" + stOp + " , EndAfter=" + enOp ; 116 117 118 // キャシュの有効期間を求めるための時刻を作成します。キャッシュは、時間指定があれば、同一時間内のみ有効です。 119 Calendar now = Calendar.getInstance(); 120 boolean nowBase = start.charAt(0) == 'H' || end.charAt(0) == 'H' ; 121 if( nowBase ) { 122 now.add( Calendar.HOUR , 1 ); // 1時間進めます。 123 now.set( Calendar.MINUTE , 0 ); // 分、秒 をリセットします。 124 now.set( Calendar.SECOND , 0 ); 125 } 126 else { 127 now.add( Calendar.YEAR , 1 ); // 1年間進めます。(現在時刻をベースに指定ない為、無制限キャッシュの意味) 128 } 129 130 maxCacheTime = now.getTimeInMillis() ; 131 } 132 133 /** 134 * 開始、または 終了の文字列から、カレンダオブジェクトを作成します。 135 * 基準となる日付に計算した結果を反映させます。 136 * 137 * prmB は、日付についての加減算処理を行うためのコマンドを指定します。 138 * ・数字 :HHMM 形式の時分です。 139 * ・H1 ~ HXXX :現在時刻に数字部分を+-します。分は0に初期化されます。 140 * 141 * @param cal 基準となる日付(Calendarオブジェクト) 142 * @param prmB 処理コマンド 143 * 144 */ 145 private void calendarCalc( final Calendar cal,final String prmB ) { 146 boolean nowBase = prmB.charAt(0) == 'H' ; 147 148 if( nowBase ) { 149 int hour = Integer.parseInt( prmB.substring( 1 ) ); 150 cal.add( Calendar.HOUR_OF_DAY,hour ); 151 cal.set( Calendar.MINUTE ,0 ); 152 cal.set( Calendar.SECOND ,0 ); 153 } 154 else { 155 int hour = Integer.parseInt( prmB.substring( 0,2 ) ); 156 int minute = Integer.parseInt( prmB.substring( 2,4 ) ); 157 cal.set( Calendar.HOUR_OF_DAY,hour ); 158 cal.set( Calendar.MINUTE ,minute ); 159 cal.set( Calendar.SECOND ,0 ); 160 } 161 } 162 163 /** 164 * 開始前設定値、または 終了後設定値の文字列から、オプション文字列を合成します。 165 * このオプションは、引数のStringBuilder に、オプションタグを追加して返します。 166 * optVal が null の場合は、処理しません。 167 * 168 * @param buf 文字列連結する StringBuilderオブジェクト。このオブジェクトに追加します。 169 * @param optVal 開始前設定値、または 終了後設定値 文字列("0000:△" 形式) 170 * 171 */ 172 private void addOption( final StringBuilder buf,final String optVal ) { 173 if( optVal != null ) { 174 int adrs = optVal.indexOf( ':' ); 175 if( adrs > 0 ) { 176 buf.append( "<option value=\"" ).append( optVal.substring( 0,adrs ) ).append( "\"" ); 177 buf.append( ">" ).append( optVal.substring( adrs+1 ) ).append( "</option>" ); 178 } 179 // 開始前設定値 が存在する場合、"0000:△" 形式必須 180 else { 181 String errMsg = "引数は、0000:△ 形式です。"; 182 throw new IllegalArgumentException( errMsg ); 183 } 184 } 185 } 186 187 /** 188 * 初期値が選択済みの 選択肢(オプション)を返します。 189 * このオプションは、引数の値を初期値とするオプションタグを返します。 190 * このメソッドでは、ラベル(短)が設定されている場合でも、これを使用せずに必ずラベル(長)を使用します。 191 * 192 * @og.rev 5.7.7.1 (2014/06/13) Selection_NULL を 継承するため、削除 193 * 194 * @param selectValue 選択されている値 195 * @param seqFlag シーケンスアクセス機能 [true:ON/false:OFF] 196 * 197 * @return オプションタグ 198 * @see #getOption( String, boolean, boolean ) 199 */ 200// public String getOption( final String selectValue,final boolean seqFlag ) { 201// return getOption( selectValue, seqFlag, false ); 202// } 203 204 /** 205 * 初期値が選択済みの 選択肢(オプション)を返します。 206 * このオプションは、引数の値を初期値とするオプションタグを返します。 207 * このメソッドでは、引数のuseShortLabelがtrueに指定された場合に、ラベル(短)をベースとした 208 * ツールチップ表示を行います。 209 * 210 * @param selectValue 選択されている値 211 * @param seqFlag シーケンスアクセス機能 [true:ON/false:OFF] 212 * @param useShortLabel ラベル(短)をベースとしたオプション表示を行うかどうか。(未使用) 213 * 214 * @return オプションタグ 215 * @see #getOption( String, boolean ) 216 */ 217 @Override 218 public String getOption( final String selectValue,final boolean seqFlag, final boolean useShortLabel ) { 219 // マッチするアドレスを探す。 220 int selected = CACHE.indexOf( "\"" + selectValue + "\"" ); 221 222 if( selected < 0 ) { 223 if( selectValue != null && selectValue.length() > 0 ) { 224 String errMsg = "時分範囲に存在しない値が指定されました。" 225 + " value=[" + selectValue + "]" 226 + HybsSystem.CR + ST_ED_STEP ; 227 LogWriter.log( errMsg ); 228 } 229 return CACHE; 230 } 231 else { 232 // "時分" 文字列の位置が、selected なので、時分の文字数+2までが、前半部分になる。(時分の文字数は4固定のはず) 233 int indx = selected + selectValue.length() + 2 ; 234 235 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE ); 236 // 3.6.0.6 (2004/10/22) シーケンスアクセス機能を指定する seqFlag を導入 237 if( seqFlag ) { 238 buf.append( "<option value=\"" ).append( selectValue ).append( "\"" ); 239 } 240 else { 241 buf.append( CACHE.substring( 0,indx ) ); 242 } 243 buf.append( " selected=\"selected\"" ); 244 buf.append( CACHE.substring( indx ) ); 245 return buf.toString() ; 246 } 247 } 248 249 /** 250 * 初期値が選択済みの 選択肢(オプション)を返します。 251 * このオプションは、引数の値を初期値とするオプションタグを返します。 252 * ※ このクラスでは実装されていません。 253 * 254 * @og.rev 5.7.7.1 (2014/06/13) Selection_NULL を 継承するため、削除 255 * 256 * @param name ラジオの name 257 * @param selectValue 選択されている値 258 * @param useLabel ラベル表示の有無 [true:有/false:無] 259 * 260 * @return オプションタグ 261 */ 262// public String getRadio( final String name,final String selectValue,final boolean useLabel ) { 263// String errMsg = "このクラスでは実装されていません。"; 264// throw new UnsupportedOperationException( errMsg ); 265// } 266 267 /** 268 * 初期値が選択済みの 選択肢(オプション)を返します。 269 * このオプションは、引数の値を初期値とするオプションタグを返します。 270 * ※ このクラスでは実装されていません。 271 * 272 * @og.rev 5.7.7.1 (2014/06/13) Selection_NULL を 継承するため、削除 273 * 274 * @param selectValue 選択されている値 275 * 276 * @return オプションタグ 277 */ 278// public String getRadioLabel( final String selectValue ) { 279// String errMsg = "このクラスでは実装されていません。"; 280// throw new UnsupportedOperationException( errMsg ); 281// } 282 283 /** 284 * 選択肢(value)に対するラベルを返します。 285 * 選択肢(value)が、存在しなかった場合は、選択肢そのものを返します。 286 * getValueLabel( XX ) は、getValueLabel( XX,false ) と同じです。 287 * 288 * @og.rev 5.7.7.1 (2014/06/13) Selection_NULL を 継承するため、削除 289 * 290 * @param selectValue 選択肢の値 291 * 292 * @return 選択肢のラベル 293 * @see #getValueLabel( String,boolean ) 294 */ 295// public String getValueLabel( final String selectValue ) { 296// return getValueLabel( selectValue,false ); 297// } 298 299 /** 300 * 選択肢(value)に対するラベルを返します。 301 * 選択肢(value)が、存在しなかった場合は、選択肢そのものを返します。 302 * このメソッドでは、短縮ラベルを返すかどうかを指定するフラグを指定します。 303 * getValueLabel( XX,false ) は、getValueLabel( XX ) と同じです。 304 * 305 * @param selectValue 選択肢の値 306 * @param flag 短縮ラベルを [true:使用する/false:しない](未使用) 307 * 308 * @return 選択肢のラベル 309 * @see #getValueLabel( String ) 310 */ 311 @Override 312 public String getValueLabel( final String selectValue,final boolean flag ) { 313 // あろうがなかろうが、選択肢そのものを返します。 314 return selectValue; 315 } 316 317 /** 318 * マルチ・キーセレクトを使用するかどうかを返します。 319 * true:使用する。false:使用しない です。 320 * ただし、実際に使用するかどうかは、HTML出力時に決めることが出来ます。 321 * ここでは、USE_MULTI_KEY_SELECT が true で、USE_SIZE(=20)以上の場合に 322 * true を返します。 323 * 324 * @return 選択リストで、マルチ・キーセレクトを使用するかどうか(true:使用する)(false固定) 325 */ 326 @Override 327 public boolean useMultiSelect() { 328 return true; 329 } 330 331 /** 332 * オブジェクトのキャッシュが時間切れかどうかを返します。 333 * キャッシュが時間切れ(無効)であれば、true を、有効であれば、 334 * false を返します。 335 * 336 * @return キャッシュが時間切れなら true 337 */ 338 @Override 339 public boolean isTimeOver() { 340 return System.currentTimeMillis() > maxCacheTime ; 341 } 342}