    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.List;
    019import java.util.ArrayList;
    020import java.util.Collections;                                                                           // 6.3.9.0 (2015/11/06)
    021
    022/**
    023 * HybsTimerTaskManager.java は、HybsTimerTask オブジェクトを管理しているクラスです。
    024 *
    025 * HybsTimerTask は、タスクとして一定間隔で実行されます。オブジェクトが生成されてから、
    026 * 実行中のタスクを、このクラスで管理することにより、個別に削除、生成、全件終了等の制御が
    027 * 可能になります。
    028 *
    029 * @version  4.0
    030 * @author   Kazuhiko Hasegawa
    031 * @since    JDK5.0,
    032 */
    033public class HybsTimerTaskManager implements Cleanable {
    034        private final List<HybsTimerTask> list = Collections.synchronizedList( new ArrayList<>() );             // 6.3.9.0 (2015/11/06)
    035
    036        /**
    037         * デフォルトコンストラクター
    038         *
    039         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    040         */
    041        public HybsTimerTaskManager() { super(); }              // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    042
    043        /**
    044         * HybsTimerTask クラスの 実オブジェクトを管理のため、登録します。
    045         *
    046         * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD)
    047         *
    048         * @param task HybsTimerTaskオブジェクト
    049         */
    050        public void addTask( final HybsTimerTask task ) {
    051                if( task != null ) {                            // 6.3.9.0 (2015/11/06) task の nullチェックを行います。
    052                        list.add( task );
    053                }
    054        }
    055
    056        /**
    057         * このタイマータスクオブジェクトを削除します。
    058         * このとき、すでにタイマータスク自信でキャンセルされているオブジェクトの
    059         * 削除も行います。
    060         *
    061         * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD)
    062         *
    063         * @param key  HybsTimerTask のユニークキー
    064         *
    065         * @return 結果(削除成功 true/ 削除できなかった false )
    066         */
    067        public boolean cancelTask( final int key ) {
    068                synchronized( list ) {
    069                        list.stream()
    070                                .filter(  task -> task != null && task.isAlive() && key == task.getUniqKey() )
    071                                .forEach( task -> task.cancel() );
    072                }
    073                taskCleaning();                 // 6.3.9.0 (2015/11/06)
    074
    075                return true;                    // なくても true を返す。
    076        }
    077
    078        /**
    079         * このタイマータスクオブジェクトを削除します。
    080         *
    081         * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD)
    082         *
    083         * @param  name  HybsTimerTask の名前
    084         *
    085         * @return 結果(削除成功 true/ 削除できなかった false )
    086         */
    087        public boolean cancelTask( final String name ) {
    088                if( name == null ) { return false; }
    089
    090                synchronized( list ) {
    091                        list.stream()
    092                                .filter(  task -> task != null && task.isAlive() && name.equals( task.getName() ) )
    093                                .forEach( task -> task.cancel() );
    094                }
    095                taskCleaning();                 // 6.3.9.0 (2015/11/06)
    096
    097                return true;                    // なくても true を返す。
    098        }
    099
    100        /**
    101         * 現在実行中の全てのタイマータスクオブジェクトを削除します。
    102         * (org.opengion.fukurou.util.Cleanable の実装)。
    103         *
    104         * @og.rev 4.0.0.0 (2005/01/31) 新規追加
    105         * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD)
    106         *
    107         */
    108        public void clear() {
    109                synchronized( list ) {
    110                        list.stream()
    111                                .filter(  task -> task != null )
    112                                .forEach( task -> task.cancel() );
    113
    114                        list.clear();
    115                }
    116
    117        }
    118
    119        /**
    120         * 現在実行中の、タイマータスクを、すべて返します。
    121         *
    122         * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD)
    123         *
    124         * @return タイマータスクの配列
    125         */
    126        public HybsTimerTask[] toArray() {
    127                taskCleaning();                 // 6.3.9.0 (2015/11/06)
    128
    129                synchronized( list ) {
    130                        return list.toArray( new HybsTimerTask[list.size()] );
    131                }
    132
    133        }
    134
    135        /**
    136         * 現在実行中の、タイマータスクの件数を返します。
    137         *
    138         * タスクがすでに 終了していたり、null 化されているかをチェックし、
    139         * 不要なタスクは、削除します。
    140         *
    141         * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD)
    142         *
    143         * @return タイマータスクの件数
    144         */
    145        public int size() {
    146                taskCleaning();                 // 6.3.9.0 (2015/11/06)
    147
    148                return list.size();
    149        }
    150
    151        /**
    152         * 現在実行中の、タイマータスクに、同一の Name 属性を持ったタスクが存在するかどうか。
    153         *
    154         * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD)
    155         *
    156         * @param  nm タイマータスクの、Name 属性
    157         *
    158         * @return 存在する：true / 存在しない：false
    159         */
    160        public boolean contains( final String nm ) {
    161                // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method
    162                // 条件組み入れ注意
    163                return nm != null &&
    164                                list.stream()
    165                                        .filter( task -> task != null && nm.equals( task.getName() ) )
    166                                        .findFirst()                                    // 1件目をピックアップ
    167                                        .isPresent();                                   // あれば true, なければ false
    168        }
    169
    170        /**
    171         * 現在実行中の、タイマータスクから、活きているタスクのみに List をクリーニングします。
    172         *
    173         * この処理を実行すると、とりあえず現時点で生きているタスクのみに再編成します。
    174         *
    175         * @og.rev 6.3.9.0 (2015/11/06) 新規追加
    176         */
    177        private void taskCleaning() {
    178                list.removeIf( task -> task == null || !task.isAlive() );
    179
    180        }
    181}