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.fukurou.util; 017 018import java.util.TimerTask; 019import java.util.Date; 020// import java.text.DateFormat; 021// import java.text.SimpleDateFormat; 022// import java.util.Locale; 023 024import java.util.Map; 025import java.util.HashMap; 026import java.util.concurrent.atomic.AtomicInteger; // 5.5.2.6 (2012/05/25) findbugs対応 027 028/** 029 * HybsTimerTask.java は、String 型キーにString型値を Map するクラスです。 030 * 031 * HTMLのPOST/GET等の受け渡しや、String型の引数が多い場合に効果があります。 032 * 特に、getHybsTimerTask( String[] param ) による属性リスト作成は、 033 * HTMLタグの属性定義を行う上で,非常に便利に利用できます。 034 * 035 * この実装は同期化されません。 036 * 037 * @version 4.0 038 * @author Kazuhiko Hasegawa 039 * @since JDK5.0, 040 */ 041public abstract class HybsTimerTask extends TimerTask implements Comparable<HybsTimerTask> { // 4.3.3.6 (2008/11/15) Generics警告対応 042// private static int counter = 0; 043 private static AtomicInteger counter = new AtomicInteger(); // 5.5.2.6 (2012/05/25) findbugs対応 044 045// private final DateFormat formatter = new SimpleDateFormat( "HHmmss",Locale.JAPAN ); 046 private final int uniqKey ; // タイマータスクのユニークキー 047 private final long createTime = System.currentTimeMillis() ; // オブジェクトが生成された時刻 048 private String name = null; // タイマータスクの名称 049 private String comment = null; // タイマータスクの説明 050 // 3.2.2.0 (2003/05/31) HybsTimerTask に対して、設定値を渡せるように変更。 051 private Map<String,String> paramMap = null; // タイマータスクのパラメータ 3.6.0.7 (2004/11/06) 052 private String body = null; // タイマータスクのボディー要素 053 private String startTime = "000000"; // 24時間制の開始時刻 054 private String stopTime = "000000"; // 24時間制の終了時刻 055 private int startStop = 0; // 24時間制の日付またがりをチェック。 056 private boolean aliveFlag = true ; // 活きているかどうか 057 private int errorSleep = 0; // TimerTask がエラーのときのスリープ時間(s) 3.7.0.4 (2005/03/14) 058 059 /** 060 * デフォルトコンストラクター 061 * オブジェクトは、newInstance でのみ、生成されます。 062 * 063 * @og.rev 5.5.2.6 (2012/05/25) findbugs対応。staticフィールドへの書き込みに、AtomicInteger を利用します。 064 */ 065 public HybsTimerTask() { 066 // 4.3.4.4 (2009/01/01) 067// super(); 068// uniqKey = counter++; 069 uniqKey = counter.getAndIncrement() ; // 5.5.2.6 (2012/05/25) findbugs対応 070 } 071 072 /** 073 * このタイマータスクによって実行されるアクションです。 074 * ここでは、エラートラップを入れていますので、サブクラスで 075 * 再定義できないように、final 化しています。 076 * サブクラスでは、stratDaemon() をオーバーライドしてください。 077 * 078 * @see java.util.TimerTask#run() 079 * @see #startDaemon() 080 */ 081 @Override 082 public final void run() { 083 try { 084 if( isExecution() ) { 085 startDaemon(); 086 } 087 } 088 catch (Throwable th) { 089 // 3.7.0.4 (2005/03/14) 090 if( errorSleep > 0 ) { 091 try { Thread.sleep( errorSleep * 1000L ); } 092 catch( InterruptedException ex ) { LogWriter.log( ex ); } 093 System.out.println( th.getMessage() ); 094 } 095 else { 096 cancel(); 097 throw new RuntimeException( th ); 098 } 099 } 100 } 101 102 /** 103 * このタイマータスクによって実行されるアクションです。 104 * run メソッドより呼ばれます。 105 * サブクラスでは、startDaemon() をオーバーライドしてください。 106 * 107 * @see #run() 108 */ 109 abstract protected void startDaemon() ; 110 111 /** 112 * このタイマータスクによって初期化されるアクションです。 113 * サブクラスでは、initDaemon() をオーバーライドしてください。 114 * 115 */ 116 public void initDaemon() { 117 // ここでは処理を行いません。 118 } 119 120 /** 121 * タイマータスクの名称(ユニークキー)を設定します。 122 * 123 * @param nm タイマータスクの名称 124 */ 125 public void setName( final String nm ) { 126 name = nm; 127 } 128 129 /** 130 * タイマータスクの名称(ユニークキー)を取得します。 131 * 132 * @return タイマータスクの名称 133 */ 134 public String getName() { 135 return name; 136 } 137 138 /** 139 * タイマータスクの説明を設定します。 140 * 141 * @param cmt タイマータスクの説明 142 */ 143 public void setComment( final String cmt ) { 144 comment = cmt; 145 } 146 147 /** 148 * タイマータスクの説明を取得します。 149 * 150 * @return タイマータスクの説明 151 */ 152 public String getComment() { 153 return comment; 154 } 155 156 /** 157 * このオブジェクトの内部ユニークキー値を返します。 158 * オブジェクト生成毎に、+1 されて、内部に持っています。 159 * 160 * @return オブジェクトの内部ユニークキー 161 */ 162 public int getUniqKey() { 163 return uniqKey; 164 } 165 166 /** 167 * このオブジェクトが生成された時刻をミリ秒で返します。 168 * オブジェクト生成時に、System.currentTimeMillis() の値を取得しています。 169 * 170 * @return オブジェクトが生成された時刻(ミリ秒) 171 */ 172 public long getCreateTime() { 173 return createTime; 174 } 175 176 /** 177 * 内部で使用するパラメータを設定します。 178 * 179 * 外部より、引数として渡されてきます。これを利用して、各サブシステムは、 180 * パラメーターを設定したり、初期化したり利用出来ます。 181 * 182 * @param map パラメータマップ 183 */ 184 public void setParameter( final Map<String,String> map ) { 185 if( map != null ) { 186 paramMap = new HashMap<String,String>( map ); 187 } 188 } 189 190 /** 191 * 内部で使用するパラメータのキーに対する値を取得します。 192 * 193 * 各サブシステムは、パラメーターを設定したり、初期化したり利用出来ます。 194 * 195 * @param key 引数のキー 196 * 197 * @return キーに対する値 198 */ 199 public String getValue( final String key ) { 200 if( paramMap != null && key != null ) { 201 return paramMap.get( key ); 202 } 203 204 return null; 205 } 206 207 /** 208 * 内部で使用するBody要素の値を設定します。 209 * 210 * 外部より、引数として渡されてきます。これを利用して、各サブシステムは、 211 * パラメーターを設定したり、初期化したり利用出来ます。 212 * 213 * @param body Body要素の値 214 */ 215 public void setBody( final String body ) { 216 this.body = body ; 217 } 218 219 /** 220 * 内部で使用するBody要素の値を取得します。 221 * 222 * 各サブシステムは、パラメーターを設定したり、初期化したり利用出来ます。 223 * 224 * @return Body要素の値 225 */ 226 public String getBody() { 227 return body ; 228 } 229 230 /** 231 * 24時間制(YYMMDD)の開始時刻を設定します。 232 * 233 * 指定時刻範囲内での実行のみ許可するように開始時刻を設定します。 234 * これは、タイマーで指定した間隔ごとにチェックを入れるので、チェック時間が 235 * 長い場合は、正確に開始時刻から始まるというものではありません。 236 * 初期値は、"000000" です。 237 * 238 * @param st 開始時刻 239 */ 240 public void setStartTime( final String st ) { 241 if( st == null || st.length() != 6 ) { 242 String errMsg = "startTime is inaccurate." + 243 "startTime=[" + st + "]" ; 244 throw new RuntimeException( errMsg ); 245 } 246 startTime = st ; 247 initStartStop(); 248 } 249 250 /** 251 * 24時間制(YYMMDD)の終了時刻を設定します。 252 * 253 * 指定時刻範囲内での実行のみ許可するように終了時刻を設定します。 254 * これは、タイマーで指定した間隔ごとにチェックを入れるので、チェック時間が 255 * 長い場合は、正確に終了時刻で終了するというものではありません。 256 * (終了時刻を越えてからの新規実行はありません。) 257 * 初期値は、"000000" です。 258 * 259 * @param st 終了時刻 260 */ 261 public void setStopTime( final String st ) { 262 if( st == null || st.length() != 6 ) { 263 String errMsg = "stopTime is inaccurate." + 264 "stopTime=[" + st + "]" ; 265 throw new RuntimeException( errMsg ); 266 } 267 stopTime = st ; 268 initStartStop(); 269 } 270 271 /** 272 * TimerTask がエラー発生時のスリープ時間(s) 設定します(初期値:0)。 273 * 274 * これは、予期せぬエラー(たとえば、データベースが落ちていたなど)が 275 * 発生したときでも、TimerTask を終了させずに、Sleep させて待機させる 276 * 事により、原因が除去された場合に、自動復帰するようにします。 277 * これに、0 を設定すると、エラー時に即 終了します。 278 * 設定は、秒で指定してください。 279 * 280 * @param erTime スリープ時間(s)(初期値:0) 281 */ 282 public void setErrorSleepSec( final int erTime ) { 283 errorSleep = erTime ; 284 } 285 286 /** 287 * 24時間制の開始/終了時刻の日付またがりを初期設定します。 288 * 289 * 開始時刻、終了時刻は、24時間制でしか指定できません。(日付指定できない) 290 * そのため、朝7:00から夜22:00などの 開始<終了 の時は単純な範囲チェックで 291 * 判断できますが、夜22:00から朝7:00に実行したい場合は、異なるチェックが 292 * 必要になります。 293 * また、開始時刻と終了時刻が未設定の場合や、同じ時刻の場合は、常に実行する必要が 294 * あります。これらのチェックを毎回行うのではなく、開始/終了時刻設定時にチェックして 295 * おきます。 296 * 297 */ 298 private void initStartStop() { 299 if( startTime == null || stopTime == null ) { 300 startStop = 0; 301 } 302 else { 303 startStop = startTime.compareTo( stopTime ); 304 } 305 } 306 307 /** 308 * 実行可能時間内かどうかを判定します。 309 * 310 * 設定された開始時刻と終了時刻に基づいて、現時刻で実行可能かどうか 311 * 判断します。 312 * 313 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。 314 * 315 * @return (true:実行許可 false:停止) 316 */ 317 private boolean isExecution() { 318 boolean rtnFlag = false; 319// String time = formatter.format( new Date() ); 320 String time = HybsDateUtil.getDate( "HHmmss" ); // 5.5.7.2 (2012/10/09) HybsDateUtil を利用 321 322 if( startStop == 0 ) { 323 rtnFlag = true; 324 } 325 else if( startStop < 0 ) { 326 if( startTime.compareTo( time ) < 0 && 327 time.compareTo( stopTime ) < 0 ) { 328 rtnFlag = true; 329 } 330 } 331 else if( startStop > 0 ) { 332 if( startTime.compareTo( time ) < 0 || 333 time.compareTo( stopTime ) < 0 ) { 334 rtnFlag = true; 335 } 336 } 337 return rtnFlag; 338 } 339 340 /** 341 * このオブジェクトと指定されたオブジェクトの順序を比較します。 342 * このオブジェクトが指定されたオブジェクトより小さい場合は負の整数、 343 * 等しい場合はゼロ、大きい場合は正の整数を返します。 344 * 345 * @param other 比較対象の Object 346 * 347 * @return このオブジェクトが指定されたオブジェクトより小さい場合は負の整数、等しい場合はゼロ、大きい場合は正の整数 348 * @throws ClassCastException 指定されたオブジェクトの型が原因で、この Object と比較できない場合 349 */ 350// public int compareTo( final Object obj ) { 351// HybsTimerTask other = (HybsTimerTask)obj ; 352 public int compareTo( final HybsTimerTask other ) { // 4.3.3.6 (2008/11/15) Generics警告対応 353 354 if( name == null && other.name != null ) { return -1; } 355 if( name != null && other.name == null ) { return 1; } 356 357 if( name != null && other.name != null ) { 358 int nmComp = name.compareTo( other.name ); 359 if( nmComp != 0 ) { return nmComp; } 360 } 361 362 return ( uniqKey - other.uniqKey ); 363 } 364 365 /** 366 * このオブジェクトの文字列表現を返します。 367 * 基本的にデバッグ目的に使用します。 368 * 369 * @return このクラスの文字列表現 370 */ 371 @Override 372 public String toString() { 373 return name + " [" + uniqKey + "]"; 374 } 375 376 /** 377 * このオブジェクトと他のオブジェクトが等しいかどうかを示します。 378 * 379 * @param object 比較対象の参照オブジェクト 380 * 381 * @return 引数に指定されたオブジェクトとこのオブジェクトが等しい場合は true、そうでない場合は false 382 */ 383 @Override 384 public boolean equals( final Object object ) { 385 if( object == null || !getClass().equals( object.getClass() ) ) { return false; } 386 if( !super.equals( object ) ) { return false; } 387 388 HybsTimerTask other = (HybsTimerTask)object; 389 return uniqKey == other.uniqKey ; 390 } 391 392 /** 393 * オブジェクトが生存しているかどうかを判定します。 394 * 395 * @return 生存しているかどうか。true:生存 / false:キャンセル済み 396 */ 397 public boolean isAlive() { 398 return aliveFlag ; 399 } 400 401 /** 402 * オブジェクトのハッシュコード値を返します。 403 * 404 * @return このオブジェクトのハッシュコード値 405 */ 406 @Override 407 public int hashCode() { 408 return uniqKey ; 409 } 410 411 /** 412 * このタイマータスクのcancel() メソッドをオーバーライドします。 413 * 414 * @return キャンセルが正常に終了できたかどうか 415 * @see java.util.TimerTask#cancel() 416 */ 417 @Override 418 public boolean cancel() { 419 if( aliveFlag ) { 420 System.out.println(); 421 System.out.println( toString() + " " + new Date() + " Stoped" ); 422 aliveFlag = false; // cancelTask を呼ぶ前に必ず『false』にしておく。 423 } 424 return super.cancel(); 425 } 426}