View Javadoc

1   package org.eparapher.core.tools;
2   
3   import java.io.BufferedReader;
4   import java.io.File;
5   import java.io.FileNotFoundException;
6   import java.io.IOException;
7   import java.io.InputStreamReader;
8   import java.net.Socket;
9   
10  import org.apache.log4j.Logger;
11  import org.eparapher.core.EParapherManager;
12  import org.eparapher.core.interfaces.EParapherSettings;
13  
14  
15  public class OODaemonManager {
16  
17  	private static Logger  log = Logger.getLogger(OODaemonManager.class);
18  
19  	public static String[] OODIRPATTERN    = { "ooo-", "openoffice-", "OpenOffice.org " };
20  	public static String[] WININSTALLDIR   = { "C:\\Program Files\\", "C:\\Program Files\\OpenOffice.org 2.4\\program" };
21  	public static String[] MACINSTALLDIR   = { "/Applications/" };
22  	public static String[] NIXINSTALLDIR   = { "/usr/lib", "/lib", "/usr/local/lib" };
23  	public static String[] NIX64INSTALLDIR = { "/usr/lib64", "/lib64", "/usr/local/lib64", "/usr/lib", "/lib", "/usr/local/lib"};
24  	public static String[] BINDIR          = { "/usr/bin", "/bin", "/usr/local/bin" };
25  
26  	private long    TIMETOWAITFORDAEMON = 2000L;
27  	
28  	private Process oofficeProcess;
29  	private EParapherSettings settings;
30  	
31  	//Singleton
32  	private static OODaemonManager singleton;
33  	public static OODaemonManager getInstance() {
34  		if (singleton == null)
35  			singleton = new OODaemonManager();
36  		return singleton;
37  	}
38  	public OODaemonManager() {
39  		oofficeProcess = null;
40  		settings=EParapherManager.getInstance().getSettings();
41  		return;
42  	}
43  
44  	/**
45  	 * Test if OpenOffice binary exists and can be executed 
46  	 * @return
47  	 * @throws FileNotFoundException
48  	 * @throws IOException
49  	 */
50  	public boolean canExecuteOpenOfficeBinary() {
51  		boolean ret = true;
52  		File soffice = new File(getsofficefile());
53  
54  		if (!soffice.exists()) {
55  			log.error("Open Office binary not found : " +soffice.getAbsolutePath());
56  			ret = false;
57  		}
58  		if (!soffice.isFile()) {
59  			log.error("Open Office binary isn't a file : " + soffice.getAbsolutePath());
60  			ret = false;			
61  		}
62  		if (!soffice.canExecute()) {
63  			log.error("Cannot execute soffice binary file");
64  			ret = false;
65  		}
66  		return ret;
67  
68  	}
69  
70  	@SuppressWarnings("static-access")
71  	public void start() {
72  		if (canExecuteOpenOfficeBinary() && !isOpenOfficeRunning()) {
73  			Runtime r = Runtime.getRuntime();
74  			try {				
75  
76  				//Build command line, exec directory and environnement
77  				String cmd = getStartCmd();
78  
79  				//Run the command
80  				oofficeProcess = r.exec( cmd );
81  				
82  				Thread.currentThread().sleep(TIMETOWAITFORDAEMON);
83  
84  				log.info("OpenOffice daemon started");
85  			} catch (IOException e) {
86  				log.error("Error while starting OpenOffice Process : "+e.getLocalizedMessage(),e);
87  			} catch (InterruptedException e) {
88  				log.error("Error while starting OpenOffice Process : "+e.getLocalizedMessage(),e);
89  			}	
90  		}
91  	}
92  	public void stop() {
93  
94  		if (oofficeProcess == null) {
95  			log.warn("Cannot stop OpenOffice daemon as it hasn't be started");
96  			return;
97  		}
98  		
99  		log.info("Stop OpenOffice daemon.");
100 		String osName = System.getProperty("os.name");
101 		if (osName.startsWith("Windows")) {
102 			try {
103 				if (osName.equals("Windows Vista"))
104 					Runtime.getRuntime().exec("taskkill /F /IM soffice.exe /T");
105 				else Runtime.getRuntime().exec("tskill soffice");
106 				oofficeProcess = null;
107 			} catch (IOException e) {
108 				log.error("Error while killing Open Office Process : "+e.getLocalizedMessage(),e);
109 			} 
110 		} else if (osName.startsWith("SunOS") || osName.startsWith("Linux")|| osName.startsWith("AIX")) {
111 			try {
112 				unixKillOpenOffice();
113 				oofficeProcess = null;
114 			} catch (IOException e) {
115 				log.error("Error while killing Open Office Process : "+e.getLocalizedMessage(),e);
116 			}
117 		} else {
118 			log.warn("Unsupported OS for OpenOffice, killing impossible");
119 	    } 
120 	}
121 
122 	public boolean isOpenOfficeRunning() {
123 		if (oofficeProcess == null) 
124 			return false; 
125 		//Try a	tcp connect on localhost:8100
126 		try{
127 			  Socket connection = new Socket("localhost", 8100);
128 			  connection.close();
129 			  return true;
130 			}catch(Exception e){
131 			  log.warn("Could not connect or connection was interrupted.");
132 			  return false;
133 			}
134 		//return (oofficeProcess != null) ? true : false;
135 	}
136 	
137     /**
138     * Kill OpenOffice on Unix.
139     */
140     private static void unixKillOpenOffice() throws IOException
141     {
142        Runtime runtime = Runtime.getRuntime();
143        String pid = getOpenOfficeProcessID();
144        if (pid != null)
145        {
146           while (pid != null)
147           {
148              String[] killCmd = {"/bin/bash", "-c", "kill -9 "+pid};
149              runtime.exec(killCmd);
150 	         // Is another OpenOffice prozess running?
151              pid = getOpenOfficeProcessID();
152           }
153        }
154     }
155 
156     /**
157     * Get OpenOffice process id for Unix.
158     */
159     private static String getOpenOfficeProcessID() throws IOException {
160        Runtime runtime = Runtime.getRuntime();
161 	       // Get prozess id
162        String[] getPidCmd = {"/bin/bash", "-c", "ps -e|grep soffice|awk '{print $1}'"};
163        Process getPidProcess = runtime.exec(getPidCmd);
164 	       // Read prozess id
165        InputStreamReader isr = new InputStreamReader(getPidProcess.getInputStream());
166        BufferedReader br = new BufferedReader(isr);
167        return br.readLine();
168     }
169 
170     private String getStartCmd() {
171     	String cmd = getsofficefile() + " " + settings.getOpenOfficeDaemonParams();
172 		return cmd;
173 	}
174 
175 	private String getsofficefile() {
176 		String binary = "soffice";
177 		if (JVMSettings.isWindowsOS())
178 			binary += ".exe";
179 		return settings.getOpenOfficeBinaryPath() + File.separator + binary;
180 	}
181 
182 	public void addOOLibPath() {
183 		// Add OpenOffice library path to java.library.path
184 		String env = System.getProperty("java.library.path");
185 		if (env.indexOf(settings.getOpenOfficeLibraryPath())<0) {
186 			env = env + File.pathSeparator + settings.getOpenOfficeLibraryPath();
187 			System.setProperty("java.library.path",env);
188 		}
189 	}
190 	
191 	public static String findOOBinaryPath() {
192 		String[] binDirs;
193 		if (!JVMSettings.isWindowsOS()) {
194 			binDirs = BINDIR;
195 			for (int i = 0; i < binDirs.length; i++) {
196 				String dirtotest = binDirs[i];
197 				log.debug("scanning for OpenOffice binary in : " + dirtotest );
198 				File f = new File(dirtotest + File.separator + "soffice");
199 				if ( f!=null && f.exists() && f.canExecute() ) {
200 					log.info("Found OpenOffice binary in : " + dirtotest);
201 					return dirtotest;
202 				}
203 			}
204 		} else {
205 			binDirs = WININSTALLDIR;
206 			for (int i = 0; i < binDirs.length; i++) {
207 				String dirtoscan = binDirs[i];
208 				log.debug("Scanning for OpenOffice binary in : " + dirtoscan );
209 				File fDirToScan = new File(dirtoscan);
210 				if (fDirToScan!=null && fDirToScan.exists() && fDirToScan.canRead()) {
211 					File[] instDirs = fDirToScan.listFiles();
212 					for (File file : instDirs) {
213 						String path = file.getAbsolutePath() + File.separator + "program" + File.separator + "soffice.exe";
214 						log.debug("scanning for OpenOffice binary in : " + path );
215 						File ootest  = new File(path);
216 						if (ootest.exists() && ootest.canExecute()) {
217 							log.info("Found OpenOffice binary in : " + path);
218 							return path;
219 						}
220 					}
221 				} else {
222 					log.info("Cannot scan for OO binary in : " + dirtoscan );
223 
224 				}
225 			}
226 		}
227 		log.info("OpenOffice binary not found.");
228 		return "Not found";
229 	}
230 
231 	public static String findOOLibPath() {
232 
233 		String[] libDirs;
234 		String   oopath = null;
235 
236 		//Settings OS Paths
237 		if (JVMSettings.isWindowsOS()) {
238 			libDirs = WININSTALLDIR;
239 		} else {
240 			if (JVMSettings.isMacOS()) {
241 				libDirs = MACINSTALLDIR;
242 				//store.setDefault(PreferenceConstants.P_LOCALOOLIBPATH,     "/Applications/OpenOffice.org 2.4.app/");
243 			} else {
244 				//Test if 64bit *nix /usr/lib64
245 				if (System.getProperty("os.arch").equals("amd64"))
246 					libDirs = NIX64INSTALLDIR;
247 				else
248 					libDirs = NIXINSTALLDIR;
249 			}
250 		}
251 			
252 		for (int i = 0; i < libDirs.length; i++) {
253 			File dirtoscan = new File(libDirs[i]);
254 			log.debug("Scanning for OpenOffice libraries in : " + libDirs[i] );
255 			if (dirtoscan.isDirectory() && dirtoscan.canRead()) {
256 				File[] dirContent = dirtoscan.listFiles();
257 				for ( int j = 0; j < dirContent.length; j++ ) {
258 					File file = dirContent[j];
259 					for( String name : OODIRPATTERN ) {
260 						//TODO : Compare Versions of Open Office
261 						if ( file.getAbsolutePath().indexOf(name) > 0 )
262 							oopath = file.getAbsolutePath();
263 					}
264 				}
265 			}
266 		}
267 		if (oopath==null)
268 			return "Not found";
269 		else log.info("Found OpenOffice path : " + oopath);
270 		return oopath;
271 	}
272 
273 	public static String getsofficeParameters() {
274 		//store.setDefault(PreferenceConstants.P_LOCALOOPDFOPTIONS,    "-headless -norestore -accept=\"socket,host=127.0.0.1,port=8100;urp;StarOffice.NamingService\"");
275 		//store.setDefault(PreferenceConstants.P_LOCALOOEDITOROPTIONS, "-nologo -nodefault -norestore -accept=pipe,name=" + user + "_Office;urp;StarOffice.NamingService");
276 		//store.setDefault(PreferenceConstants.P_LOCALOOPDFOPTIONS,      "-headless -accept=socket,host=127.0.0.1,port=8100;urp;");
277 		//store.setDefault(PreferenceConstants.P_LOCALOOEDITOROPTIONS,   "-nologo -nodefault -norestore -accept=pipe,name=" + user + "_Office;urp;StarOffice.NamingService");
278 
279 		if (JVMSettings.isWindowsOS())
280 			return "-headless -nodefault -norestore -accept=\"socket,host=127.0.0.1,port=8100;urp;StarOffice.NamingService\"";
281 		else
282 			return "-headless -accept=socket,host=127.0.0.1,port=8100;urp;";
283 	}
284 
285 }