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.hayabusa.report2;
017    
018    import java.io.File;
019    import java.io.IOException;
020    
021    import org.opengion.fukurou.util.AbstractObjectPool;
022    import org.opengion.fukurou.util.Cleanable;
023    import org.opengion.fukurou.util.FileUtil;
024    import org.opengion.hayabusa.common.HybsSystem;
025    import org.opengion.hayabusa.common.SystemManager;
026    
027    /**
028     * Sofficeのプロセスを管ç�?�™るファクトリクラスですã?
029     * プロセスプã?ルの実è£??、AbstractObjectPoolを継承して実è£?�•れてã�?�¾すã?
030     *
031     * プロセスの初期生æ?数は0ですã?æœ?¤§生æ?数は、シスãƒ?ƒ リソースのREPORT_MAX_PROCESS_COUNTで
032     * 定義されますã?またã?生存時間ã?、REPORT_PROCESS_ALIVEで定義されてã�?�¾すã?
033     *
034     * プロセスをå?て終äº?�™るには、clearメソãƒ?ƒ‰を呼び出しますã?
035     * clearメソãƒ?ƒ‰は、Cleanableインターフェースの実è£?�¨してçµ?�¿込まれã?SytemManagerに登録されるためã?
036     * Tomcat終äº?™‚に、è?動的にプロセスが終äº?�•れますã?
037     * ä½?�—、貸しå?し中(処ç�?¸­)のプロセスは、AbstractObjecgPoolの実è£?�‹らã?終äº?�•れなã�?�Ÿめã?別の方法で
038     * 明示çš?�«killするå¿?¦�がありまã�?
039     *
040     * @version  4.0
041     * @author   Hiroki Nakamura
042     * @since    JDK5.0,
043     */
044    public final class ProcessFactory {
045    
046            /**
047             * プロセスプã?ル
048             */
049            private static ProcessPool pp = new ProcessPool() ;
050    
051            /** Cleanable インターフェースによる初期化å?ç�?*/
052            static {
053                    Cleanable clr = new Cleanable() {
054                            public void clear() {
055                                    ProcessFactory.clear();
056                            }
057                    };
058                    SystemManager.addCleanable( clr );
059    
060                    // 5.2.2.0 (2010/11/01) 循環参ç?解消ã?ため、SystemManager から移å‹?
061                    Cleanable clr2 = new Cleanable() {
062                            public void clear() {
063                                    ProcessFactory.kill();
064                            }
065                    };
066                    SystemManager.addCleanable( clr2 , true );      // コンãƒ?‚­スト終äº?™‚のみ呼び出ã�?
067            }
068    
069            /**
070             * ãƒ?ƒ•ォルトコンストラクターをprivateにしてã€?
071             * オブジェクトã?生æ?をさせなã�?‚ˆã�?�«するã€?
072             */
073            private ProcessFactory() {
074            }
075    
076            /**
077             * OpenOfficeのプロセスを生成しますã?
078             *
079             * @return      sofficeのプロセス
080             */
081            public static SOfficeProcess newInstance() {
082                    return pp.newInstance();
083            }
084    
085            /**
086             * OpenOfficeのプロセスをリリースしますã?
087             *
088             * @param  soffice SOfficeProcessオブジェクãƒ?
089             */
090            public static void release( final SOfficeProcess soffice ) {
091                    pp.release( soffice );
092            }
093    
094            /**
095             * OpenOfficeのプロセスをクローズしますã?
096             *
097             * @param   soffice SOfficeProcessオブジェクãƒ?
098             */
099            public static void remove( final SOfficeProcess soffice ) {
100                    pp.remove( soffice );
101            }
102    
103            /**
104             * プã?ルされてã�?‚‹OpenOfficeのプロセスをå?てクローズしますã?
105             */
106            public static void clear() {
107                    pp.clear();
108            }
109    
110            /**
111             * 全てのsoffice.binプロセスをKILLしますã?
112             * アプリケーションの終äº??ç�?�§実行しますã?
113             * OS名がWindowsを含ã‚??合ã?taskkill、それ以外ã?場合ã?killallしますã?
114             * 又ã?プロセス終äº?¾Œにコピã?された設定ファイルを削除しますã?
115             *
116             * @og.rev 4.3.0.0 (2008/07/18) 追åŠ?
117             * @og.rev 4.3.0.0 (2008/07/22) 設定ファイルの削除を追åŠ?
118             * @og.rev 4.3.5.0 (2009/02/01) Exception をそれぞれã?Exceptionにåˆ?�‘て捕らえるã€?
119             */
120            public static void kill() {
121                    try {
122                            final String osName = HybsSystem.sys( "OS_INFO" ); //System.getProperty("os.name");
123    //                      if( osName.indexOf( "Windows" ) != -1 ){
124    //                              // 4.3.0.0 (2008/07/18) Windoesのtaskkillを利用してsoffice.binのタスクを強制終äº?�—ますã?
125    //                              new ProcessBuilder( "cmd.exe","/c","taskkill","/F","/IM","soffice.bin" ).start().waitFor();
126    //                      }
127    //                      else{
128    //                              // 4.3.0.0 (2008/07/24) Windowsではなã�??合ã?killallコマンãƒ?
129    //                              new ProcessBuilder( "killall","-9","-w","soffice.bin" ).start().waitFor();
130    //                      }
131                            if( osName.indexOf( "Windows" ) >= 0 ){
132                                    // 4.3.0.0 (2008/07/18) Windoesのtaskkillを利用してsoffice.binのタスクを強制終äº?�—ますã?
133                                    new ProcessBuilder( "cmd.exe","/c","taskkill","/F","/IM","soffice.bin" ).start().waitFor();
134                            }
135                            else{
136                                    // 4.3.0.0 (2008/07/24) Windowsではなã�??合ã?killallコマンãƒ?
137                                    new ProcessBuilder( "killall","-9","-w","soffice.bin" ).start().waitFor();
138                            }
139    
140                            // 4.3.0.0 (2008/07/22) 設定ファイル(SOfficeProcessでãƒ?‚£レクトリを設å®?をå?削除しますã?
141                            FileUtil.deleteFiles( new File( SOfficeProcess.ENV_DIR ) );
142                    }
143    //              catch( Exception ex ) {
144    //                      ex.printStackTrace();
145    //              }
146                    catch( IOException ex ) {
147                            ex.printStackTrace();
148                    }
149                    catch( InterruptedException ex ) {
150                            ex.printStackTrace();
151                    }
152                    catch( RuntimeException ex ) {
153                            ex.printStackTrace();
154                    }
155            }
156    
157            /**
158             * 現在の状態をæ–?­—å?で返しますã?
159             *
160             * @return  現在の状æ…?
161             */
162            public static String information() {
163                    return pp.toString();
164            }
165    
166            /**
167             * ProcessPool は、AbstractObjectPool を継承した オブジェクトã?ールですã?
168             *
169             * OpenOfficeのプロセスをã?ールしますã?
170             *
171             * @version  4.0
172             * @author   Hiroki Nakamura
173             * @since    JDK5.0,
174             */
175            protected static class ProcessPool extends AbstractObjectPool<SOfficeProcess> {
176                    // 環å¢?ƒ•ァイル作æ?の識別用
177                    private int count = 0;
178    
179                    /**
180                     * 初期処ç�?‚’行いますã?
181                     */
182                    protected ProcessPool() {
183                            init( 0, HybsSystem.sysInt( "REPORT_MAX_PROCESS_COUNT")
184                                            , true, HybsSystem.sysInt( "REPORT_PROCESS_ALIVE" ) );
185                    }
186    
187                    /**
188                     * soffieのプロセスオブジェクトを作æ?しますã?
189                     *
190                     * @og.rev 4.3.5.0 (2009/02/01) Exception ではなくã?RuntimeException に変更
191                     * @og.rev 5.1.7.0 (2010/06/01) TCP接続対å¿?
192                     *
193                     * @return OpenOfficeのプロセス
194                     */
195                    protected SOfficeProcess createInstance() {
196                            SOfficeProcess soffice = null;
197                            try {
198                                    // 5.1.7.0 (2010/06/01) TCP接続対å¿?
199    //                              soffice = new SOfficeProcess( "env_" + count );
200                                    if( "TCP".equalsIgnoreCase( HybsSystem.sys( "REPORT_OOO_CONN_TYPE" ) ) ) {
201                                            soffice = new SOfficeProcessTcp( "env_" + count, HybsSystem.sysInt( "REPORT_OOO_MIN_PORT" ) );
202                                    }
203                                    else {
204                                            soffice = new SOfficeProcess( "env_" + count );
205                                    }
206                                    soffice.bootstrap();
207    
208                                    count++;
209                            }
210    //                      catch( Exception ex ) {
211                            catch( RuntimeException ex ) {
212                                    System.out.println( "[ERROR]OOo:Failed to Connect Soffice! " + ex.getMessage() );
213                            }
214                            return soffice;
215                    }
216    
217                    /**
218                     * オブジェクトã?ールから削除するときに呼ばれますã?
219                     * こã?メソãƒ?ƒ‰でå�?‚ªブジェクトごとの終äº??ç�?‚’行いますã?
220                     *
221                     * @param soffice OpenOfficeのプロセス
222                     */
223                    protected void objectFinal( final SOfficeProcess soffice ) {
224                            soffice.close();
225                    }
226            }
227    }
228