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        @Override       // Cleanable
109        public void clear() {
110                synchronized( list ) {
111                        list.stream()
112                                .filter(  task -> task != null )
113                                .forEach( task -> task.cancel() );
114
115                        list.clear();
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                        return list.toArray( new HybsTimerTask[0] );    // 8.5.4.2 (2024/01/12) PMD 7.0.0 OptimizableToArrayCall 対応
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}