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.IOException;
019 import java.net.InetSocketAddress;
020 import java.net.Socket;
021
022 import org.opengion.hayabusa.common.HybsSystemException;
023
024 /**
025 * OpenOfficeのプロセスを表すクラスですã?
026 *
027 * こã?クラスでは、TCPによりプロセスに接続を行いますã?
028 * 基本çš?�«は、パイプ名による接ç¶?{@link SOfficeProcess})を利用すべきですがã€?
029 * x64環å¢?�§ã€?4Bit版ã?Javaを起動したå?合ã?パイプ接続では、UnsatisfiedLinkErrorが発生しますã?
030 * こã?ような場合では、TCP接続を利用することで、上記エラーを回避することができますã?
031 *
032 * @version 4.0
033 * @author Hiroki Nakamura
034 * @since JDK5.0,
035 */
036 public final class SOfficeProcessTcp extends SOfficeProcess {
037
038 private static final boolean[] ports = new boolean[512];
039 private static final Object lock = new Object();
040
041 private final int initPort;
042 private final int thisPort;
043
044 /**
045 * コンストラクタですã?
046 *
047 * @param id プロセスID
048 * @param initPort 初期ポã?ãƒ?
049 */
050 protected SOfficeProcessTcp( final String id, final int initPort ) {
051 super( id );
052
053 this.initPort = initPort;
054 this.thisPort = getThisPort();
055 }
056
057 /**
058 * TCP接続ã?ート番号を取得しますã?
059 *
060 * @return TCP接続ã?ート番号
061 */
062 private int getThisPort() {
063 try {
064 Thread.sleep( 100 ); // åˆ?–後すぐにopenされると、ã?ートチェãƒ?‚¯で引っかかるたã‚?00msWAIT
065 }
066 catch( InterruptedException ex ) {
067 // ここの Exception は、無視しますã?
068 }
069
070 int port = -1;
071 synchronized( lock ) {
072 for( int i=0; i<ports.length; i++ ) {
073 if( !ports[i] ) {
074 if( checkPort( initPort + i ) ) {
075 // System.out.println( "port=" + ( initPort + i ) + "を使用済みにマã?クしましたã€? );
076 ports[i] = true;
077 // System.out.println( "port=" + ( initPort + i ) + "を使用しますã?" );
078 port = initPort + i;
079 break;
080 }
081 // else {
082 // System.out.println( "port=" + ( initPort + i ) + "は使用中のためスキãƒ??しますã?" );
083 // }
084 }
085 }
086 }
087 if( port < 0 ) {
088 throw new HybsSystemException( "TCP接続ã?ートを取得することができません" );
089 }
090
091 return port;
092 }
093
094 /**
095 * 引数のポã?トが使用中かどã�?�‹を調べますã?
096 *
097 * @param port ポã?ト番号
098 *
099 * @return 使用中かどã�?�‹
100 */
101 private boolean checkPort( final int port ) {
102 boolean flg = false;
103 Socket sk = null;
104 try {
105 sk = new Socket();
106 sk.connect( new InetSocketAddress( "localhost", port ) );
107 }
108 catch( IOException ex ) {
109 flg = true;
110 }
111 finally {
112 try {
113 // sk.close();
114 if( sk != null ) { sk.close(); } // 5.5.2.6 (2012/05/25) findbugs対å¿?
115 }
116 catch( IOException ex ) {
117 ex.printStackTrace();
118 }
119 }
120 return flg;
121 }
122
123 /**
124 * Pipe名をキーにOpenOfficeのプロセスに接続するためã?æ–?—å?を生成しますã?
125 * ※TCP接続ã?場合ã?キーのPipe名ã?無視されã?å†?ƒ¨çš?�«管ç�?�•れるポã?ト番号ä¸?¦§より
126 * 接続ã?ートを取得しますã?
127 *
128 * @param key Pipeå�?無視されまã�?
129 *
130 * @return 接続文字å?
131 */
132 @Override
133 protected String getConnParam( final String key ) {
134 System.out.println( "[INFO]OOo:TCP Connection Start,port=" + thisPort );
135 // return "uno:socket,host=localhost,tcpNoDelay=1,port=" + String.valueOf( thisPort ) + ";urp;StarOffice.ComponentContext";
136 return "uno:socket,host=localhost,tcpNoDelay=1,port=" + thisPort + ";urp;StarOffice.ComponentContext";
137 }
138
139 /**
140 * Pipe名をキーにOpenOfficeのプロセスを生成するためã?パラメーターæ–?—å?を生成しますã?
141 * ※TCP接続ã?場合ã?キーのPipe名ã?無視されã?å†?ƒ¨çš?�«管ç�?�•れるポã?ト番号ä¸?¦§より
142 * 接続ã?ートを取得しますã?
143 *
144 * @param key Pipeå�?無視されまã�?
145 *
146 * @return プロセス生æ?パラメーター
147 */
148 @Override
149 protected String getProcParam( final String key ) {
150 // return "-accept=socket,host=localhost,port=" + String.valueOf( thisPort ) + ";urp;";
151 return "-accept=socket,host=localhost,port=" + thisPort + ";urp;";
152 }
153
154 /**
155 * プロセスを終äº?�—ますã?
156 * またã?同時に環å¢?¨定用のファイルも削除しますã?
157 * ここでは、ã?ロセスを終äº?�™ると同時に、そのプロセスのポã?ト番号を開放しã?
158 * 次に起動されるプロセスで利用できるようにしますã?
159 */
160 @Override
161 public void close() {
162 super.close();
163 synchronized( lock ) {
164 ports[thisPort-initPort] = false;
165 }
166 // System.out.println( "[INFO]OOo:TCP Connection End(Release),port=" + String.valueOf( thisPort ) );
167 System.out.println( "[INFO]OOo:TCP Connection End(Release),port=" + thisPort );
168 }
169 }
170