    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.taglib;
    017
    018import org.opengion.hayabusa.common.HybsSystem;
    019import org.opengion.hayabusa.common.SystemManager;
    020import org.opengion.hayabusa.db.DBColumn;
    021import org.opengion.hayabusa.db.DBTableModel;
    022import org.opengion.hayabusa.db.DBTableModelUtil;
    023import org.opengion.hayabusa.html.ViewForm;
    024import org.opengion.hayabusa.html.ViewFormFactory;
    025import org.opengion.hayabusa.resource.ResourceManager;
    026import org.opengion.fukurou.util.HybsTimerTask;
    027import org.opengion.fukurou.util.HybsTimerTaskManager;
    028import org.opengion.fukurou.util.ToString;                                              // 6.1.1.0 (2015/01/17)
    029import org.opengion.fukurou.util.ArraySet;                                              // 6.4.3.4 (2016/03/11)
    030
    031import static org.opengion.fukurou.util.StringUtil.nval ;
    032
    033import java.util.Timer;
    034import java.util.Set;                                                                                   // 6.4.3.4 (2016/03/11)
    035import java.util.Map;
    036import java.util.HashMap;
    037import java.util.Iterator;
    038
    039/**
    040 * アプリケーション共有のタイマー機能を用いて、繰り返しスケジュールを設定するタグです。
    041 *
    042 * タイマースケジュールは、帳票デーモンや、再編成処理、定期的バッチ処理など、エンジン上の
    043 * スレッドで動作するスケジュールを登録します。
    044 * スケジュールすべきクラスは、HybsTimerTask を拡張(extends)しておく必要があります。
    045 *
    046 * @og.formSample
    047 * ●形式：&lt;og:schedule timerTask="･･･" name="･･･" command="[SET|VIEW|REMOVE|CANCEL]" ･･･ /&gt;
    048 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
    049 *
    050 * ●Tag定義：
    051 *   &lt;og:schedule
    052 *       command            【TAG】コマンド (SET,VIEW,REMOVE,CANCEL)をセットします(初期値:SET)
    053 *       timerTask        ○【TAG】処理を実行するクラス名(HybsTimerTask のサブクラス)を指定します(必須)。
    054 *       name             ○【TAG】名称(ユニークキー)を設定します(必須)。
    055 *       comment            【TAG】タイマータスクの説明を設定します
    056 *       singleton          【TAG】Name属性が同一のタスクを２重登録出来ないよう[true/false]にします(初期値:true[出来ない])
    057 *       delay              【TAG】ミリ秒単位の遅延時間を設定します(初期値:0)
    058 *       period             【TAG】ミリ秒単位の繰り返し間隔を設定します(初期値:60000)
    059 *       fixedDelay         【TAG】固定遅延実行を指定するかどうか[true:固定遅延実行/false:固定頻度実行]を設定します(初期値:true)
    060 *       keys               【TAG】HybsTimerTask に渡す為のキー情報、CSV形式で複数指定します
    061 *       vals               【TAG】HybsTimerTask に渡す為の値を、CSV形式で複数指定します
    062 *       prmKeys            【TAG】HybsTimerTask に渡すパラメータのキー情報を、CSV形式で指定します(分解しない)。
    063 *       prmVals            【TAG】HybsTimerTask に渡すパラメータの値を、CSV形式で指定します(分解しない)。
    064 *       startTime          【TAG】24時間制(YYMMDD)の開始時刻を設定します(初期値:000000)
    065 *       stopTime           【TAG】24時間制(YYMMDD)の終了時刻を設定します(初期値:000000)
    066 *       scope              【TAG】キャッシュする場合のスコープ(local,request,page,session,application)を指定します(初期値:local)
    067 *       tableId            【TAG】(通常は使いません)結果をDBTableModelに書き込んで、sessionに登録するときのキーを指定します
    068 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    069 *   &gt;   ... Body ...
    070 *   &lt;/og:schedule&gt;
    071 *
    072 * ●使用例
    073 *      帳票デーモンスケジュール登録
    074 *      period は、ｍｓ単位で指定する必要があるため、１０００倍しています。
    075 *      &lt;og:schedule
    076 *          command     = &quot;{&#064;CMD}&quot;
    077 *          scope       = &quot;request&quot;
    078 *          timerTask   = &quot;org.opengion.hayabusa.report.ReportDaemon&quot;
    079 *          name        = &quot;{&#064;NAME}&quot;
    080 *          comment     = &quot;Start-up By {&#064;USER.INFO}&quot;
    081 *          singleton   = &quot;true&quot;
    082 *          delay       = &quot;0&quot;
    083 *          period      = &quot;{&#064;PERIOD}000&quot;
    084 *          fixedDelay  = &quot;true&quot;
    085 *          keys        = &quot;SYSTEM_ID,DMN_GRP&quot;
    086 *          vals        = &quot;{&#064;SYSTEM_ID},{&#064;DMN_GRP}&quot;
    087 *      /&gt;
    088 *
    089 * @og.group その他部品
    090 *
    091 * @version  4.0
    092 * @author   Kazuhiko Hasegawa
    093 * @since    JDK5.0,
    094 */
    095public class ScheduleTag extends CommonTagSupport {
    096        /** このプログラムのVERSION文字列を設定します。   {@value} */
    097        private static final String VERSION = "6.4.3.4 (2016/03/11)" ;
    098        private static final long serialVersionUID = 643420160311L ;
    099
    100        /** command 引数に渡す事の出来る コマンド  セット {@value} */
    101        public static final String CMD_SET   = "SET";
    102        /** command 引数に渡す事の出来る コマンド  ビュー {@value} */
    103        public static final String CMD_VIEW   = "VIEW";
    104        /** command 引数に渡す事の出来る コマンド  リムーブ {@value} */
    105        public static final String CMD_REMOVE   = "REMOVE";
    106        /** command 引数に渡す事の出来る コマンド  キャンセル {@value} */
    107        public static final String CMD_CANCEL   = "CANCEL";
    108
    109        // 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    110        private static final Set<String> COMMAND_SET = new ArraySet<>( CMD_SET , CMD_VIEW , CMD_REMOVE , CMD_CANCEL );
    111
    112        // 3.5.2.0 (2003/10/20) 結果を DBTableModel として、scope 属性に登録する。
    113        private String            tableId          = HybsSystem.TBL_MDL_KEY;
    114
    115        private String  command         = CMD_SET;
    116        private String  timerTask       ;                       // 処理を実行する HybsTimerTask のクラス名を指定します。
    117        private String  name            ;                       // タイマータスクの名称(ユニークキー)
    118        private String  comment         ;                       // タイマータスクの説明
    119        private long    delay           ;                       // タスクが実行される前のミリ秒単位の遅延(初期値:0)
    120        private long    period          = 60000l;       // 連続するタスク実行のミリ秒単位の時間(初期値:60000 mS)
    121        private boolean fixedDelay      = true;         // 固定遅延実行(true)/固定頻度実行(false) (初期値:true)
    122        private int             uniqKey         = -1;           // ありえない値を初期設定しておく。
    123        private boolean singleton       = true;         // Name属性が同一のタスクを２重登録出来ないようにする(初期値:true)
    124
    125        private static final long FIXED_RATE_MIN_TIME = 1000;   // 固定頻度実行時の最小繰り返し時間
    126
    127        private static final String TIMER_KEY           = HybsSystem.SCEDULE_KEY;
    128        private static final String TIMERTASK_KEY       = HybsSystem.SCEDULE_TASK_KEY;
    129
    130        // 6.2.5.1 (2015/06/12) CSV形式のkeys,vals引数(CSV引数)対応。
    131        private String          keys            ;                       // タイマータスクへ渡すキー配列
    132        private String          vals            ;                       // タイマータスクへ渡すバリュー配列
    133
    134        private String          body            ;                       // タイマータスクへ渡すボディー要素
    135        private String          startTime       = "000000";     // 24時間制の開始時刻
    136        private String          stopTime        = "000000";     // 24時間制の終了時刻
    137
    138        // 3.5.2.0 (2003/10/20) 結果を DBTableModel として、scope 属性に登録する。
    139        private String          scope           = "local";      // local は互換性のため。"request","page","session","application"
    140
    141        // 3.7.0.4 (2005/03/14) 帳票デーモンに、エラー時にスリープして待機する機能を追加
    142        private final int ERROR_SLEEP_TIME = HybsSystem.sysInt( "REPORT_DAEMON_ERROR_SLEEP_TIME" );
    143
    144        // 4.0.0 (2006/11/17) HybsTimerTaskManager を static クラスから通常オブジェクトとして管理。
    145        private static final HybsTimerTaskManager TASK_MANAGER ;                        // 6.4.1.1 (2016/01/16) taskManager  → TASK_MANAGER  refactoring
    146
    147        // 4.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理
    148        // 4.3.6.2 (2009/04/15) コンテキスト終了時のみclear()されるように対応
    149        static {
    150                TASK_MANAGER = new HybsTimerTaskManager();
    151                // 4.3.6.2 (2009/04/15)
    152                SystemManager.addCleanable( TASK_MANAGER, true );       // コンテキスト終了時のみ呼び出す
    153        }
    154
    155        /**
    156         * デフォルトコンストラクター
    157         *
    158         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    159         */
    160        public ScheduleTag() { super(); }               // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    161
    162        /**
    163         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
    164         *
    165         * @og.rev 3.2.2.0 (2003/05/31) HybsTimerTask に対して、設定値を渡せるように変更。
    166         *
    167         * @return      後続処理の指示( EVAL_BODY_BUFFERED )
    168         */
    169        @Override
    170        public int doStartTag() {
    171                return EVAL_BODY_BUFFERED ;     // Body を評価する。( extends BodyTagSupport 時)
    172        }
    173
    174        /**
    175         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
    176         *
    177         * @og.rev 3.2.2.0 (2003/05/31) HybsTimerTask に対して、設定値を渡せるように変更。
    178         *
    179         * @return      後続処理の指示(SKIP_BODY)
    180         */
    181        @Override
    182        public int doAfterBody() {
    183                body = getBodyString();
    184
    185                return SKIP_BODY ;
    186        }
    187
    188        /**
    189         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    190         *
    191         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    192         * @og.rev 3.6.0.8 (2004/11/19) DBTableModel をセーブする時に、トランザクションチェックを行います。
    193         * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    194         *
    195         * @return      後続処理の指示
    196         */
    197        @Override
    198        public int doEndTag() {
    199                debugPrint();           // 4.0.0 (2005/02/28)
    200                if( !check( command, COMMAND_SET ) ) { return EVAL_PAGE ; }
    201
    202                if( "session".equals( scope ) ) {
    203                        startQueryTransaction( tableId );               // 3.6.0.8 (2004/11/19)
    204                }
    205
    206                // 3.6.0.8 (2004/11/19) トランザクションチェックを行います。
    207                if( commandExec( command ) ) {
    208                        return EVAL_PAGE ;              // ページの残りを評価する。
    209                }
    210                else {
    211                        jspPrint( "ScheduleTag Query処理が割り込まれました。DBTableModel は登録しません。" );
    212                        return SKIP_PAGE;
    213                }
    214        }
    215
    216        /**
    217         * タグリブオブジェクトをリリースします。
    218         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    219         *
    220         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
    221         * @og.rev 3.2.2.0 (2003/05/31) HybsTimerTask に対して、設定値を渡せるように変更。
    222         * @og.rev 3.5.2.0 (2003/10/20) 結果を DBTableModel として、scope 属性に登録する。
    223         */
    224        @Override
    225        protected void release2() {
    226                super.release2();
    227                command         = CMD_SET;
    228                timerTask       = null;         // 処理を実行する HybsTimerTask のクラス名を指定します。
    229                name            = null;         // タイマータスクの名称(ユニークキー)
    230                comment         = null;         // タイマータスクの説明
    231                delay           = 0;            // タスクが実行される前のミリ秒単位の遅延(初期値:0)
    232                period          = 60000;        // 連続するタスク実行のミリ秒単位の時間(初期値:60000 mS)
    233                fixedDelay      = true;         // 固定遅延実行(true)/固定頻度実行(false) (初期値:true)
    234                uniqKey         = -1;           // ありえない値を初期設定しておく。
    235                singleton       = true;         // Name属性が同一のタスクを２重登録出来ないようにする(初期値:true)
    236                keys            = null;         // タイマータスクへ渡すキー配列
    237                vals            = null;         // タイマータスクへ渡すバリュー配列
    238                startTime       = "000000";     // 24時間制の開始時刻
    239                stopTime        = "000000";     // 24時間制の終了時刻
    240                tableId         = HybsSystem.TBL_MDL_KEY;               //
    241                scope           = "local";      // local は互換性のため。"request","page","session","application"
    242        }
    243
    244        /**
    245         * コマンドを実行します。
    246         *
    247         * コマンドは,HTMLから(SET/VIEW/REMOVE/CANCEL)指定されますので,setCommand()メソッドで
    248         * 登録します。
    249         * コマンドを登録すると同時に,実行も行ないます。
    250         *
    251         * @og.rev 3.5.2.0 (2003/10/20) viewAttribute()メソッドを、全てで実行します。
    252         * @og.rev 3.6.0.8 (2004/11/19) 正常に登録できたかどうかを、返します。
    253         * @og.rev 4.0.0.0 (2007/10/18) メッセージリソース統合( setMsg() ⇒ setLbl )
    254         *
    255         * @param   command コマンド (public static final 宣言されている文字列)
    256         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ScheduleTag.CMD_SET">コマンド定数</a>
    257         *
    258         * @return 正常かどうか(true:正常/false:異常)
    259         */
    260        protected boolean commandExec( final String command ) {
    261                if( CMD_SET.equals( command ) ) {
    262                        setAttribute();
    263                        setLbl( "MSG0059" );    // 登録しました。
    264                        jspPrint( getMsglbl() );
    265                }
    266                else if( CMD_VIEW.equals( command ) ) {
    267                        jspPrint( String.valueOf( TASK_MANAGER.size() ) );
    268                        setLbl( "MSG0033" );    // 　件検索しました。
    269                        jspPrint( getMsglbl() );
    270                }
    271                else if( CMD_REMOVE.equals( command ) ) {
    272                        removeAttribute();
    273                        setLbl( "MSG0061" );    // 削除しました。
    274                        jspPrint( getMsglbl() );
    275                }
    276                else if( CMD_CANCEL.equals( command ) ) {
    277                        cancelAttribute();
    278                        setLbl( "MSG0063" );    // 完了しました。
    279                        jspPrint( getMsglbl() );
    280                }
    281                return viewAttribute();
    282        }
    283
    284        /**
    285         * HybsTimerTask を登録します。
    286         *
    287         * @og.rev 3.2.2.0 (2003/05/31) HybsTimerTask に対して、設定値を渡せるように変更。
    288         * @og.rev 3.6.0.7 (2004/11/06) パラメータをMapで渡すように変更。
    289         * @og.rev 3.7.0.4 (2005/03/14) HybsTimerTask に setErrorSleepSec メソッドの追加
    290         * @og.rev 6.2.5.1 (2015/06/12) CSV形式のkeys,vals引数(CSV引数)対応。
    291         */
    292        @SuppressWarnings(value={"unchecked"})
    293        private void setAttribute() {
    294                // シングルトンで、かつ、すでに、同一名称のタスクが
    295                // 含まれている場合は、セットしない。
    296                if( singleton && TASK_MANAGER.contains( name ) ) { return ; }
    297
    298                // 6.2.5.1 (2015/06/12) CSV形式のkeys,vals引数(CSV引数)対応。
    299                final Map<String,String> param = getCSVParameter( keys,vals );
    300
    301                final HybsTimerTask task = HybsSystem.newInstance( timerTask );
    302                TASK_MANAGER.addTask( task );
    303
    304                task.setName( name );
    305                task.setComment( comment );
    306                task.setParameter( param );             // 3.6.0.7 (2004/11/06)
    307                task.setBody( body );
    308                task.setStartTime( startTime );
    309                task.setStopTime( stopTime );
    310                task.setErrorSleepSec( ERROR_SLEEP_TIME );      // 3.7.0.4 (2005/03/14)
    311                task.initDaemon();
    312
    313                // 3.6.1.0 (2005/01/05) Timer 同一スレッドのため、個別に作成する。
    314                Map<String,Timer> timerMap = (Map<String,Timer>)getContextAttribute( TIMER_KEY );
    315                if( timerMap == null ) { timerMap = new HashMap<>(); }
    316
    317                Timer timer = timerMap.get( name );
    318                if( timer == null ) { timer = new Timer( true ); }
    319
    320                if( fixedDelay ) {
    321                        if( period > 0 ) { timer.schedule( task,delay,period ); }
    322                        else             { timer.schedule( task,delay ); }
    323                }
    324                else {
    325                        if( period < FIXED_RATE_MIN_TIME ) { period = FIXED_RATE_MIN_TIME; }
    326                        timer.scheduleAtFixedRate( task,delay,period );
    327                }
    328
    329                // 3.6.1.0 (2005/01/05) Timer 同一スレッドのため、個別に作成する。
    330                timerMap.put( name,timer );
    331                setContextAttribute( TIMER_KEY,timerMap );
    332        }
    333
    334        /**
    335         * HybsTimerTask を一覧表示します。
    336         *
    337         * @og.rev 3.5.2.0 (2003/10/20) 結果を DBTableModel として、scope 属性に登録する。
    338         * @og.rev 3.5.6.1 (2004/06/25) lang 言語コード 属性を削除します。
    339         * @og.rev 3.6.0.8 (2004/11/19) DBTableModel をセーブする時に、トランザクションチェックを行います。
    340         * @og.rev 3.6.0.8 (2004/11/19) 正常に登録できたかどうかを、返します。
    341         *
    342         * @return 正常かどうか(true:正常/false:異常)
    343         */
    344        private boolean viewAttribute() {
    345                final HybsTimerTask[] tasks = TASK_MANAGER.toArray();
    346                final DBTableModel table = makeDBTable( tasks );
    347
    348                if( "local".equals( scope ) ) {
    349                        if( table != null ) {
    350                                final ViewForm form = ViewFormFactory.newInstance( "HTMLTable" );
    351                                form.clear();
    352                                form.init( table );
    353                                jspPrint( form.create() );
    354                        }
    355                }
    356                else {
    357                        super.setScope( scope );                // 3.6.0.9 (2004/12/03)
    358                        // 3.6.0.8 (2004/11/19) トランザクションチェックを行います。
    359                        return commitTableObject( tableId, table );
    360                }
    361                return true;
    362        }
    363
    364        /**
    365         * HybsTimerTask を削除します。
    366         *
    367         * @og.rev 3.2.2.0 (2003/05/31) キャンセルを名前でもできる様にロジック追加。
    368         *
    369         */
    370        private void removeAttribute() {
    371                if( uniqKey >= 0 ) {
    372                        TASK_MANAGER.cancelTask( uniqKey );
    373                }
    374                else {
    375                        TASK_MANAGER.cancelTask( name );
    376                }
    377        }
    378
    379        /**
    380         * Timer そのものをキャンセルします。
    381         *
    382         * すべての、HybsTimerTask は、削除されます。
    383         *
    384         * @og.rev 3.6.1.0 (2005/01/05) Timer 同一スレッドのため、個別に作成する。
    385         */
    386        @SuppressWarnings(value={"unchecked"})
    387        private void cancelAttribute() {
    388                TASK_MANAGER.clear();
    389
    390                // 3.6.1.0 (2005/01/05)
    391                final Map<String,Timer> timerMap = (Map<String,Timer>)getContextAttribute( TIMER_KEY );
    392                if( timerMap != null ) {
    393                        final Iterator<Timer> iterator = timerMap.values().iterator();  // 4.3.3.6 (2008/11/15) Generics警告対応
    394                        while( iterator.hasNext() ) {
    395                                (iterator.next()).cancel();     // 4.3.3.6 (2008/11/15) Generics警告対応
    396                        }
    397                        timerMap.clear();
    398                }
    399                removeContextAttribute( TIMER_KEY );
    400        }
    401
    402        /**
    403         * 【TAG】コマンド (SET,VIEW,REMOVE,CANCEL)をセットします(初期値:SET)。
    404         *
    405         * @og.tag
    406         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
    407         * フィールド定数値のいづれかを、指定できます。
    408         * 何も設定されない、または、null の場合は、"SET" が初期値にセットされます。
    409         *
    410         * @param       cmd コマンド (public static final 宣言されている文字列)
    411         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ScheduleTag.CMD_SET">コマンド定数</a>
    412         */
    413        public void setCommand( final String cmd ) {
    414                command = nval( getRequestParameter( cmd ),command );
    415        }
    416
    417        /**
    418         * 【TAG】処理を実行するクラス名(HybsTimerTask のサブクラス)を指定します。
    419         *
    420         * @og.tag 処理を実行する HybsTimerTask のクラス名を指定します。
    421         *
    422         * @param   val クラス名
    423         */
    424        public void setTimerTask( final String val ) {
    425                timerTask = getRequestParameter( val );
    426        }
    427
    428        /**
    429         * 【TAG】名称(ユニークキー)を設定します。
    430         *
    431         * @og.tag タイマータスクの名称(ユニークキー)を設定します。
    432         *
    433         * @param   nm タイマータスクの名称
    434         */
    435        public void setName( final String nm ) {
    436                name = getRequestParameter( nm );
    437        }
    438
    439        /**
    440         * 【TAG】タイマータスクの説明を設定します。
    441         *
    442         * @og.tag タイマータスクの説明を設定します。
    443         *
    444         * @param   cmt タイマータスクの説明
    445         */
    446        public void setComment( final String cmt ) {
    447                comment = getRequestParameter( cmt );
    448        }
    449
    450        /**
    451         * 【TAG】ミリ秒単位の遅延時間を設定します(初期値:0)。
    452         *
    453         * @og.tag タスクが実行される前のミリ秒単位の遅延を設定します(初期値:0)
    454         *
    455         * @param   val 遅延時間(ms)
    456         */
    457        public void setDelay( final String val ) {
    458                delay = nval( getRequestParameter( val ),delay );
    459        }
    460
    461        /**
    462         * 【TAG】ミリ秒単位の繰り返し間隔を設定します(初期値:60000)。
    463         *
    464         * @og.tag 連続するタスク実行のミリ秒単位の時間を設定します(初期値:60000 mS)
    465         *
    466         * @param   val 繰り返し間隔(ms)
    467         */
    468        public void setPeriod( final String val ) {
    469                period = nval( getRequestParameter( val ),period );
    470        }
    471
    472        /**
    473         * 【TAG】固定遅延実行を指定するかどうか[true:固定遅延実行/false:固定頻度実行]を設定します(初期値:true)。
    474         *
    475         * @og.tag
    476         * 固定遅延実行では、前の実行の実際の実行時間を基準にしてそれぞれの実行がスケジュールされます。
    477         * 何らかの理由で実行が遅延した場合 そのあとの実行も遅延されます。
    478         * 最終的に、実行の頻度は通常、指定した期間の対応する頻度よりも若干遅くなります
    479         *
    480         * 固定頻度実行では、最初の実行のスケジュールされた実行時間を基準にしてそれぞれの実行が
    481         * スケジュールされます。何らかの理由で実行が遅延した場合、「遅れを取り戻す」ために
    482         * 2 つ以上の実行が連続して行われます。最終的に実行の頻度は、指定した期間の対応する頻度と
    483         * 同じになります
    484         * 初期値は、true:固定遅延実行 です。
    485         *
    486         * @param   flag 遅延方式指定 [true:固定遅延実行/false:固定頻度実行]
    487         */
    488        public void setFixedDelay( final String flag ) {
    489                fixedDelay = nval( getRequestParameter( flag ),fixedDelay );
    490        }
    491
    492        /**
    493         * 【TAG】スケジュールを一意に決めるためのユニーク番号を指定します(初期値:-1)。
    494         *
    495         * @og.tag
    496         * スケジュールを削除したりする場合に、必要なユニーク番号を指定します。
    497         * 初期値は、-1:あり得ない値 です。
    498         *
    499         * @param   no ユニーク番号
    500         */
    501        public void setUniqKey( final String no ) {
    502                uniqKey = nval( getRequestParameter( no ),uniqKey );
    503        }
    504
    505        /**
    506         * 【TAG】Name属性が同一のタスクを２重登録出来ないよう[true:禁止/false:なにもない]にします(初期値:true:禁止)。
    507         *
    508         * @og.tag
    509         * 同一種類のタスクを複数同時立上げしたくない場合に、利用します。
    510         * 一般に、タイマータスクそのものが、繰り返し実行されますので、
    511         * 初期値は、２重登録禁止にしています。
    512         *
    513         * @param   flag ２重登録不可 [true:禁止/false:なにもない]
    514         */
    515        public void setSingleton( final String flag ) {
    516                singleton = nval( getRequestParameter( flag ),singleton );
    517        }
    518
    519        /**
    520         * 【TAG】HybsTimerTask に渡す為のキー情報、CSV形式で複数指定します。
    521         *
    522         * @og.tag
    523         * HybsTimerTask に渡す為の、キー情報をCSV形式で複数指定できます。
    524         * vals 属性には、キーに対応する値を、設定してください。
    525         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
    526         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
    527         *
    528         * @og.rev 3.2.2.0 (2003/05/31) 新規追加
    529         * @og.rev 3.5.6.2 (2004/07/05) CommonTagSupport#getCSVParameter を使用
    530         * @og.rev 6.2.5.1 (2015/06/12) CSV形式のkeys,vals引数(CSV引数)対応。
    531         *
    532         * @param       key キー情報(CSV形式)
    533         */
    534        public void setKeys( final String key ) {
    535                keys = key;
    536        }
    537
    538        /**
    539         * 【TAG】HybsTimerTask に渡す為の値を、CSV形式で複数指定します。
    540         *
    541         * @og.tag
    542         * キーに設定した値を、CSV形式で複数して出来ます。
    543         * 指定順序は、キーと同じにしておいて下さい。
    544         * 分解方法は、CSV変数を先に分解してから、getRequestParameter で値を取得します。
    545         * こうしないとデータ自身にカンマを持っている場合に分解をミスる為です。
    546         *
    547         * @og.rev 3.2.2.0 (2003/05/31) 新規追加
    548         * @og.rev 3.5.6.2 (2004/07/05) CommonTagSupport#getCSVParameter を使用
    549         * @og.rev 6.2.5.1 (2015/06/12) CSV形式のkeys,vals引数(CSV引数)対応。
    550         *
    551         * @param       val 値(CSV形式)
    552         */
    553        public void setVals( final String val ) {
    554                vals = val;
    555        }
    556
    557        /**
    558         * 【TAG】24時間制(YYMMDD)の開始時刻を設定します(初期値:000000)。
    559         *
    560         * @og.tag
    561         * 指定時刻範囲内での実行のみ許可するように開始時刻を設定します。
    562         * これは、タイマーで指定した間隔ごとにチェックを入れるので、チェック時間が
    563         * 長い場合は、正確に開始時刻から始まるというものではありません。
    564         * 初期値は、"000000" です。
    565         *
    566         * @og.rev 3.2.2.0 (2003/05/31) 新規追加
    567         *
    568         * @param       st 開始時刻
    569         */
    570        public void setStartTime( final String st ) {
    571                startTime = nval( getRequestParameter( st ),startTime ) ;
    572        }
    573
    574        /**
    575         * 【TAG】24時間制(YYMMDD)の終了時刻を設定します(初期値:000000)。
    576         *
    577         * @og.tag
    578         * 指定時刻範囲内での実行のみ許可するように終了時刻を設定します。
    579         * これは、タイマーで指定した間隔ごとにチェックを入れるので、チェック時間が
    580         * 長い場合は、正確に終了時刻で終了するというものではありません。
    581         * (終了時刻を越えてからの新規実行はありません。)
    582         * 初期値は、"000000" です。
    583         *
    584         * @og.rev 3.2.2.0 (2003/05/31) 新規追加
    585         *
    586         * @param       st 終了時刻
    587         */
    588        public void setStopTime( final String st ) {
    589                stopTime = nval( getRequestParameter( st ),stopTime ) ;
    590        }
    591
    592        /**
    593         * HybsTimerTask オブジェクト配列より、DBTableModel を作成して返します。
    594         * カラム名は、"TaskName","UniqKey","Comment","CreateTime","scheduledTime" です。
    595         *
    596         * @param   tasks       タイマータスクオブジェクト配列(可変長引数)
    597         *
    598         * @return      タイマータスクオブジェクトのテーブルモデル。 無ければ null
    599         */
    600        private DBTableModel makeDBTable( final HybsTimerTask... tasks ) {
    601                if( tasks == null || tasks.length == 0 ) { return null; }               // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。
    602
    603                final ResourceManager  resource  = getResource();
    604
    605                final String[] names = new String[] {
    606                                                        "TaskName","UniqKey","Comment","CreateTime","scheduledTime"
    607                                                };
    608
    609                final DBTableModel table = DBTableModelUtil.newDBTable();
    610                table.init( names.length );
    611                for( int i=0; i<names.length; i++ ) {
    612                        final DBColumn dbColumn = resource.makeDBColumn( names[i] );
    613                        table.setDBColumn( i,dbColumn );
    614                }
    615
    616                for( int i=0; i<tasks.length; i++ ) {
    617                        String[] clmVals = new String[names.length];
    618                        clmVals[0] = tasks[i].getName() ;
    619                        clmVals[1] = String.valueOf( tasks[i].getUniqKey() );
    620                        clmVals[2] = tasks[i].getComment() ;
    621                        clmVals[3] = HybsSystem.getDate( tasks[i].getCreateTime() );
    622                        clmVals[4] = HybsSystem.getDate( tasks[i].scheduledExecutionTime() );
    623                        table.addColumnValues( clmVals );
    624                }
    625
    626                return table ;
    627        }
    628
    629        /**
    630         * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
    631         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
    632         *
    633         * @og.tag
    634         * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に
    635         * 渡す場合に、通常は、session を利用します。その場合の登録キーです。
    636         * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、
    637         * この tableId 属性を利用して、メモリ空間を分けます。
    638         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
    639         *
    640         * @param       id テーブルID (sessionに登録する時のID)
    641         */
    642        public void setTableId( final String id ) {
    643                tableId = nval( getRequestParameter( id ),tableId );
    644        }
    645
    646        /**
    647         * 【TAG】キャッシュする場合のスコープ(local,request,page,session,application)を指定します(初期値:local)。
    648         *
    649         * @og.tag
    650         * "local","request","page","session","application" が指定できます。
    651         * "local" は、過去のバージョンとの互換性を保つ為の特殊な値です。
    652         * 初期値は、"local" です。
    653         *
    654         * @og.rev 3.5.2.0 (2003/10/20) 新規作成
    655         *
    656         * @param       scp     スコープ
    657         */
    658        @Override
    659        public void setScope( final String scp ) {
    660                scope = nval( getRequestParameter( scp ),scope );
    661        }
    662
    663        /**
    664         * このオブジェクトの文字列表現を返します。
    665         * 基本的にデバッグ目的に使用します。
    666         *
    667         * @return このクラスの文字列表現
    668         * @og.rtnNotNull
    669         */
    670        @Override
    671        public String toString() {
    672                return ToString.title( this.getClass().getName() )
    673                                .println( "VERSION"                             ,VERSION                )
    674                                .println( "tableId"                             ,tableId                )
    675                                .println( "command"                             ,command                )
    676                                .println( "timerTask"                   ,timerTask              )
    677                                .println( "name"                                ,name                   )
    678                                .println( "comment"                             ,comment                )
    679                                .println( "delay"                               ,delay                  )
    680                                .println( "period"                              ,period                 )
    681                                .println( "fixedDelay"                  ,fixedDelay             )
    682                                .println( "uniqKey"                             ,uniqKey                )
    683                                .println( "singleton"                   ,singleton              )
    684                                .println( "FIXED_RATE_MIN_TIME" ,FIXED_RATE_MIN_TIME)
    685                                .println( "TIMER_KEY"                   ,TIMER_KEY              )
    686                                .println( "TIMERTASK_KEY"               ,TIMERTASK_KEY  )
    687                                .println( "keys"                                ,keys                   )
    688                                .println( "vals"                                ,vals                   )
    689                                .println( "body"                                ,body                   )
    690                                .println( "startTime"                   ,startTime              )
    691                                .println( "stopTime"                    ,stopTime               )
    692                                .println( "scope"                               ,scope                  )
    693                                .println( "ERROR_SLEEP_TIME"    ,ERROR_SLEEP_TIME)
    694                                .println( "Other..."    ,getAttributes().getAttribute() )
    695                                .fixForm().toString() ;
    696        }
    697}