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.report2;
017
018import java.util.HashMap;
019import java.util.Map;
020
021/**
022 * 帳票処理を行う各スレッドを管理するクラスです。
023 *
024 * 各スレッドは、内部的にプールされます。
025 * スレッドのIDはOOoQueue#getThreadId()で返される値です。
026 * スレッドが生成されるタイミングは、そのIDで初めてスタック要求が来た(insertQueue()が呼ばれた)時です。
027 *
028 * 指定のスレッドを終了するには、funishThread( key )を呼び出します。
029 * 全てのスレッドを終了するには、funishAllThreads()を呼び出します。
030 *
031 * 現時点での実装では、生成されたスレッドに対しての監視は行っていません。
032 * これは、特定のスレッドがフリーズした際、外部から強制終了を行おうとすると、
033 * 監視スレッドもフリーズしてしまう問題があるためです。
034 * (但し、1つのsoffice.binのプロセスに対してシリアルに対して処理している限りでは、
035 *  フリーズ問題は発生しないようです)
036 *
037 * @og.group 帳票システム
038 *
039 * @version  4.0
040 * @author   Hiroki.Nakamura
041 * @since    JDK1.6
042 */
043public final class ExecThreadManager {
044
045        /**
046         * スレッドプール
047         */
048        private static final Map<String, ExecThread>    pool    = new HashMap<String, ExecThread>();
049        private static boolean debug    = false; // 4.3.0.0 (2008/07/15) デバッグ追加
050
051        /**
052         * オブジェクトの生成を禁止します
053         */
054        private ExecThreadManager() {}
055
056        /**
057         * キューを該当するスレッドにスタックする
058         *
059         * @og.rev 4.3.0.0 (2008/07/15) スレッドIDにシステムIDを付加
060         *
061         * @param       queue   ExecQueueオブジェクト
062         */
063        public static void insertQueue( final ExecQueue queue ) {
064                // 4.3.3.6 (2008/11/15) この部分は不要なので元に戻します
065                ExecThread oet = getExecThread( queue.getThreadId() );
066                oet.stackQueue( queue );
067        }
068
069        /**
070         * キューを該当するスレッドにスタックする
071         *
072         * このメソッドでは、既に同じスレッドが存在するかどうかをチェックせずに必ず
073         * 新しいスレッドを生成し、キューを処理します。
074         * また、処理が完了した後、そのスレッドは、WAITすることなく終了します。
075         *
076         * @og.rev 5.1.6.0 (2010/05/01) 新規作成
077         *
078         * @param       queue   ExecQueueオブジェクト
079         */
080        public static void insertQueueOnNewThread( final ExecQueue queue ) {
081                ExecThread oet = new ExecThread( queue.getThreadId(), debug );
082                oet.start();
083                System.out.println( "[INFO]THREAD CREATED:THREAD-ID=" + queue.getThreadId() );
084                oet.stackQueue( queue );
085                oet.finishAfterExec();
086        }
087
088        /**
089         * 該当するスレッドIDを持つスレッドを取得します。
090         * スレッドプールに存在しない場合は、新規に作成されます。
091         *
092         * @param       threadId        スレッドID
093         *
094         * @return      ExecThreadスレッド
095         */
096        private static ExecThread getExecThread( final String threadId ) {
097                ExecThread oet = null;
098                synchronized( pool ) {
099                        oet = pool.get( threadId );
100
101                        // スレッドが終了している場合は、再度作成
102                        if( oet != null && !oet.isAlive() ) {
103                                pool.remove( threadId );
104                                oet = null;
105                        }
106
107                        if( oet == null ) {
108                                // oet = new ExecThread( threadId );
109                                oet = new ExecThread( threadId, debug );
110                                oet.start();
111                                System.out.println( "[INFO]THREAD CREATED:THREAD-ID=" + threadId );
112                                pool.put( threadId, oet );
113                        }
114                }
115
116                return oet;
117        }
118
119        /**
120         * 全てのスレッドを終了します。
121         *
122         */
123        public static void finishAllThreads() {
124                synchronized( pool ) {
125                        for( ExecThread oet : pool.values() ) {
126                                oet.finish();
127                        }
128                        pool.clear();
129                        System.out.println( "[INFO]ALL THREADS FINISHED" );
130                }
131        }
132
133        /**
134         * 指定のスレッドを終了します。
135         *
136         * @param threadId スレッドID
137         */
138        public static void finishThread( final String threadId ) {
139                synchronized( pool ) {
140                        ExecThread oet = pool.remove( threadId );
141                        if( oet != null ) {
142                                oet.finish();
143                                System.out.println( "[INFO]THREAD CREATED:THREAD-ID=" + threadId );
144                        }
145                }
146        }
147
148        /**
149         * スレッド情報のマップを返します。
150         *
151         * @return      スレッド情報のマップ
152         */
153        public static Map<String, String> getThreadInfo() {
154                Map<String, String> info = new HashMap<String, String>();
155                synchronized( pool ) {
156                        for( Map.Entry<String, ExecThread> entry : pool.entrySet() ) {
157                                info.put( entry.getKey(), entry.getValue().toString() );
158                        }
159                }
160                return info;
161        }
162
163        /**
164         * デバッグフラグの設定
165         *
166         * @og.rev  4.3.0.0 (2008/07/15) デバッグ追加
167         *
168         * @param   flag デバッグフラグ [true:デバッグ/false:通常]
169         */
170        public static void setDebug ( final boolean flag ){
171                debug = flag;
172        }
173}