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     */
016    package org.opengion.fukurou.util;
017    
018    import java.util.TimerTask;
019    import java.util.Date;
020    // import java.text.DateFormat;
021    // import java.text.SimpleDateFormat;
022    // import java.util.Locale;
023    
024    import java.util.Map;
025    import java.util.HashMap;
026    import 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     */
041    public 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             * オブジェクト生成毎にã€?¼‹ï¼?されて、å?部に持ってã�?�¾すã?
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             * これにã€?¼?を設定すると、エラー時に即 終äº?�—ますã?
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             * 開始時刻、終äº?™‚刻はã€?¼’4時間制でしかæŒ?®šできませんã€?日付指定できなã�?
290             * そã?ため、朝?—:00から夜22:00などの 開始<終äº?の時ã?単純なç¯?›²チェãƒ?‚¯で
291             * 判断できますが、夜22:00から朝?—: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    }