xref: /AOO41X/test/testcommon/source/org/openoffice/test/common/SystemUtil.java (revision 44cf02803b51681da4056cdf9500cc33ee29bd2f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 package org.openoffice.test.common;
23 
24 import java.awt.Toolkit;
25 import java.awt.datatransfer.Clipboard;
26 import java.awt.datatransfer.DataFlavor;
27 import java.awt.datatransfer.StringSelection;
28 import java.awt.datatransfer.Transferable;
29 import java.io.BufferedReader;
30 import java.io.File;
31 import java.io.IOException;
32 import java.io.StringReader;
33 import java.net.InetAddress;
34 import java.net.URL;
35 import java.net.UnknownHostException;
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.Enumeration;
39 import java.util.HashMap;
40 import java.util.List;
41 import java.util.StringTokenizer;
42 import java.util.logging.Level;
43 import java.util.logging.Logger;
44 import java.util.zip.ZipEntry;
45 import java.util.zip.ZipInputStream;
46 
47 /**
48  * Utilities related to system
49  *
50  */
51 public class SystemUtil {
52 
53     private static Logger LOG = Logger.getLogger(SystemUtil.class.getName());
54 
55     private static Clipboard sysClipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
56 
57     private static final File SCRIPT_TEMP_DIR = Testspace.getFile("bin");
58 
59     private static String platform = System.getProperty("os.name");
60 
61     private static String osName = System.getProperty("os.name");
62 
63     private static String osVersion  = System.getProperty("os.version");
64 
65     private static String osArch = System.getProperty("os.arch");
66 
67     static {
68         if (isLinux()) {
69             StringBuffer output = new StringBuffer();
70             if (exec(new String[]{"lsb_release", "-is"}, output) == 0)
71                 osName = output.toString().trim();
72             output.setLength(0);
73             if (exec(new String[]{"lsb_release", "-rs"}, output) == 0)
74                 osVersion = output.toString().trim();
75         }
76     }
77 
78     /**
79      * Play beep sound! The method doesn't work, if the code is executed on
80      * Eclipse IDE.
81      *
82      */
beep()83     public static void beep() {
84         System.out.print("\007\007\007");
85         System.out.flush();
86     }
87 
isWindows()88     public static boolean isWindows() {
89         return platform.startsWith("Windows");
90     }
91 
isLinux()92     public static boolean isLinux() {
93         return platform.startsWith("Linux");
94     }
95 
isMac()96     public static boolean isMac() {
97         return platform.startsWith("Mac");
98     }
99 
isBSD()100     public static boolean isBSD() {
101         return platform.endsWith("BSD");
102     }
103 
getOSName()104     public static String getOSName() {
105         return osName;
106     }
107 
getOSVersion()108     public static String getOSVersion() {
109         return osVersion;
110     }
111 
getOSArch()112     public static String getOSArch() {
113         return osArch;
114     }
115 
116     /**
117      * Set the contents of the clipboard to the provided text
118      */
setClipboardText(String s)119     public static void setClipboardText(String s) {
120         StringSelection ss = new StringSelection(s);
121 
122         // if (OS.get() == OS.MACOSX) {
123         // // workaround MAC OS X has a bug. After setting a text into
124         // clipboard, the java program will not
125         // // receive the data written by other apllications.
126         // File file = null;
127         // try {
128         // file = File.createTempFile("SystemUtil", "SystemUtil");
129         // FileUtil.writeStringToFile(file.getAbsolutePath(), s);
130         // if (exec("pbcopy < \""+ file.getAbsolutePath() + "\"", false) == 0)
131         // return;
132         // } catch (IOException e) {
133         // // TODO Auto-generated catch block
134         // e.printStackTrace();
135         // } finally {
136         // if (file != null)
137         // file.delete();
138         // }
139         //
140         // }
141         //
142         sysClipboard.setContents(ss, ss);
143     }
144 
145     /**
146      * Get plain text from clipboard
147      *
148      * @return
149      */
getClipboardText()150     public static String getClipboardText() {
151         Transferable contents = getTransferable();
152         if (contents == null || !contents.isDataFlavorSupported(DataFlavor.stringFlavor))
153             return "";
154         try {
155             return (String) contents.getTransferData(DataFlavor.stringFlavor);
156         } catch (Exception ex) {
157             return "";
158         }
159     }
160 
getTransferable()161     private static Transferable getTransferable() {
162         // To avoid IllegalStateException, we try 25 times to access clipboard.
163         for (int i = 0; i < 25; i++) {
164             try {
165                 return sysClipboard.getContents(null);
166             } catch (IllegalStateException e) {
167                 try {
168                     Thread.sleep(200);
169                 } catch (InterruptedException e1) {
170                 }
171             }
172         }
173         throw new RuntimeException("System Clipboard is not ready");
174     }
175 
176     /**
177      * Execute a script and waiting it for finishing
178      *
179      * @param content
180      * @return
181      */
execScript(String content)182     public static int execScript(String content) {
183         StringBuffer output = new StringBuffer();
184         int code = execScript(content, output, output);
185         LOG.info(content + "\n" + "Exit Code: " + code + "\n" + output);
186         return code;
187     }
188 
189     /**
190      * Execute a script and waiting it for finishing
191      * @param content
192      * @param output
193      * @param error
194      * @return
195      */
execScript(String content, StringBuffer output, StringBuffer error)196     public static int execScript(String content, StringBuffer output, StringBuffer error) {
197         File file = null;
198         try {
199             file = FileUtil.getUniqueFile(SCRIPT_TEMP_DIR, "tempscript", ".bat");
200             FileUtil.writeStringToFile(file.getAbsolutePath(), content);
201             String[] cmd;
202             if (isWindows())
203                 cmd = new String[] { file.getAbsolutePath() };
204             else
205                 cmd = new String[] { "sh", file.getAbsolutePath() };
206             return exec(cmd, null, null, output, error);
207         } catch (Exception e) {
208             return -1;
209         } finally {
210             if (file != null && !file.delete())
211                 file.deleteOnExit();
212         }
213     }
214 
215     /**
216      * Start a background process
217      * @param cmd
218      * @param env
219      * @param dir
220      * @param output
221      * @param error
222      * @return
223      */
backgroundExec(String[] cmd, String[] env, File dir, StringBuffer output, StringBuffer error)224     public static Process backgroundExec(String[] cmd, String[] env, File dir, StringBuffer output, StringBuffer error) {
225         try {
226             Process process = Runtime.getRuntime().exec(cmd, env, dir);
227             StreamPump inputPump = new StreamPump(output, process.getInputStream());
228             StreamPump errorPump = new StreamPump(error, process.getErrorStream());
229             inputPump.start();
230             errorPump.start();
231             return process;
232         } catch (Exception e) {
233             return null;
234         }
235     }
236 
237     /**
238      * Execute the command and wait for its finishing
239      * @param cmd
240      * @param env
241      * @param dir
242      * @param output
243      * @param error
244      * @return
245      */
exec(String[] cmd, String[] env, File dir, StringBuffer output, StringBuffer error)246     public static int exec(String[] cmd, String[] env, File dir, StringBuffer output, StringBuffer error) {
247         Process process = null;
248         try {
249             LOG.log(Level.FINE,  "exec: " + Arrays.toString(cmd));
250             process = Runtime.getRuntime().exec(cmd, env, dir);
251         } catch (Exception e) {
252             e.printStackTrace();
253             return -1;
254         }
255 
256         StreamPump inputPump = new StreamPump(output, process.getInputStream());
257         StreamPump errorPump = new StreamPump(error, process.getErrorStream());
258         inputPump.start();
259         errorPump.start();
260 
261         try {
262             int code = process.waitFor();
263             inputPump.join();
264             errorPump.join();
265             return code;
266         } catch (InterruptedException e) {
267             return -2;
268         }
269     }
270 
exec(String[] cmd, StringBuffer output)271     public static int exec(String[] cmd, StringBuffer output) {
272         return exec(cmd, null, null, output, output);
273     }
274 
275     /**
276      * Make the current thread sleep some seconds.
277      *
278      * @param second
279      */
sleep(double second)280     public static void sleep(double second) {
281         try {
282             if (second > 0)
283                 Thread.sleep((long) (second * 1000));
284         } catch (InterruptedException e) {
285         }
286     }
287 
288     /**
289      * Get Information of running processes
290      *
291      */
getProcesses()292     public static List<HashMap<String, Object>> getProcesses() {
293         List<HashMap<String, Object>> ret = new ArrayList<HashMap<String, Object>>();
294         try {
295             StringBuffer output = new StringBuffer();
296             if (isWindows()) {
297                 File file = new File(SCRIPT_TEMP_DIR, "ps.vbs");
298 //              if (!file.exists()) {
299                     String contents = "Set wmi=GetObject(\"Winmgmts:\")\n\r"
300                             + "Set ps = wmi.ExecQuery(\"Select * from Win32_Process\")\n\r"
301                             + "WScript.Echo \"PID COMMAND\" \n\r"
302                             + "For Each p in ps\n\r"
303                             + "WScript.Echo p.ProcessId & \" \" & p.CommandLine\n\r"
304                             + "Next";
305                     FileUtil.writeStringToFile(file.getAbsolutePath(), contents);
306 //              }
307                 exec(new String[] { "cscript", "//Nologo", file.getAbsolutePath()}, null, null, output, output);
308             } else if (isBSD()) {
309                 exec(new String[] {"ps", "-wwo", "pid,command"}, null, null, output, output);
310             } else {
311                 exec(new String[] {"ps", "-eo", "pid,command"}, null, null, output, output);
312             }
313 
314             BufferedReader reader = new BufferedReader(new StringReader(output.toString()));
315             String line = null;
316             reader.readLine();
317             while ((line = reader.readLine()) != null) {
318                 HashMap<String, Object> p = new HashMap<String, Object>();
319                 StringTokenizer tokenizer = new StringTokenizer(line, " ", true);
320                 StringBuffer last = new StringBuffer();
321                 int col = 0;
322                 while (tokenizer.hasMoreTokens()) {
323                     String token = tokenizer.nextToken();
324                     switch (col) {
325                     case 0:
326                         if (!" ".equals(token)) {
327                             //
328                             p.put("pid", token);
329                             col++;
330                         }
331                         break;
332                     default:
333                         last.append(token);
334                         break;
335                     }
336                 }
337 
338                 p.put("command", last.toString().trim());
339                 ret.add(p);
340             }
341         } catch (IOException e) {
342 
343         }
344 
345         return ret;
346     }
347 
killProcess(String pattern)348     public static void killProcess(String pattern) {
349         List<HashMap<String, Object>> processes = SystemUtil.getProcesses();
350         for (HashMap<String, Object> p : processes) {
351             String command = (String) p.get("command");
352             String pid = (String) p.get("pid");
353             if (command != null && command.matches(pattern)) {
354                 if (isWindows()) {
355                     exec(new String[] { "taskkill", "/F", "/PID", pid }, null, null, null, null);
356                 } else {
357                     exec(new String[] { "kill", "-9", pid }, null, null, null, null);
358                 }
359             }
360         }
361     }
362 
hasProcess(String pattern)363     public static boolean hasProcess(String pattern) {
364         return findProcess(pattern) != null;
365     }
366 
findProcess(String pattern)367     public static HashMap<String, Object> findProcess(String pattern) {
368         List<HashMap<String, Object>> processes = SystemUtil.getProcesses();
369         for (HashMap<String, Object> p : processes) {
370             String command = (String) p.get("command");
371             if (command != null && command.matches(pattern)) {
372                 return p;
373             }
374         }
375 
376         return null;
377     }
378 
findProcesses(String pattern)379     public static List<HashMap<String, Object>> findProcesses(String pattern) {
380         List<HashMap<String, Object>> result = new ArrayList<HashMap<String, Object>>();
381         List<HashMap<String, Object>> processes = SystemUtil.getProcesses();
382         for (HashMap<String, Object> p : processes) {
383             String command = (String) p.get("command");
384             if (command != null && command.matches(pattern)) {
385                 result.add(p);
386             }
387         }
388 
389         return result;
390     }
391 
392     /**
393      * Get Information of running processes
394      *
395      */
getProcessPerfData(String processId)396     public static HashMap<String, Object> getProcessPerfData(String processId) {
397         try {
398             StringBuffer output = new StringBuffer();
399             if (isWindows()) {
400                 File file = new File(SCRIPT_TEMP_DIR, "pps.vbs");
401                 String contents = "Set wmi=GetObject(\"Winmgmts:\")\n\r"
402                         + "Set pps = wmi.ExecQuery(\"Select * from Win32_PerfFormattedData_PerfProc_Process Where IDProcess='" + processId+"'\")\n\r"
403                         + "WScript.Echo \"pcpu PrivateBytes WorkingSet HandleCount\" \n\r"
404                         + "For Each pp in pps \n\r"
405                         + "WScript.Echo pp.PercentProcessorTime & \" \" & Round(pp.PrivateBytes/1024) & \" \" & Round(pp.WorkingSet/1024) & \" \" & pp.HandleCount \n\r"
406                         + "Next";
407 //              String contents = "var wmi = GetObject(\"Winmgmts:\");\n"
408 //                      + "var pps = new Enumerator(wmi.ExecQuery(\"Select * from Win32_PerfFormattedData_PerfProc_Process Where IDProcess='" + processId+"'\"));\n"
409 //                      + "WScript.Echo(\"pcpu rss\");\n"
410 //                      + "for ( ; !pps.atEnd(); pps.moveNext()) {\n"
411 //                      + "var pp = pps.item();\n"
412 //                      + "WScript.Echo(pp.PercentProcessorTime + \" \" + (pp.WorkingSet/1024));\n"
413 //                      + "}";
414                 FileUtil.writeStringToFile(file.getAbsolutePath(), contents);
415                 exec(new String[] { "cscript", "//Nologo", file.getAbsolutePath()}, null, null, output, output);
416             } else {
417                 exec(new String[] {"ps", "-p", processId ,"-o", "pcpu,vsz,rss,tty"}, null, null, output, output);
418             }
419             BufferedReader reader = new BufferedReader(new StringReader(output.toString()));
420             String line = null;
421             reader.readLine();
422             if ((line = reader.readLine()) != null) {
423                 HashMap<String, Object> p = new HashMap<String, Object>();
424                 StringTokenizer tokenizer = new StringTokenizer(line, " ", true);
425                 int col = 0;
426                 while (tokenizer.hasMoreTokens()) {
427                     String token = tokenizer.nextToken();
428                     switch (col) {
429                     case 0:
430                         if (!" ".equals(token)) {
431                             //
432                             p.put("pcpu", Double.parseDouble(token));
433                             col++;
434                         }
435                         break;
436                     case 1:
437                         if (!" ".equals(token)) {
438                             //
439                             p.put("vsz", Long.parseLong(token));
440                             col++;
441                         }
442                         break;
443                     case 2:
444                         if (!" ".equals(token)) {
445                             //
446                             p.put("rss", Long.parseLong(token));
447                             col++;
448                         }
449                         break;
450                     case 3:
451                         if (!" ".equals(token)) {
452                             //
453                             try {
454                                 p.put("handles", Long.parseLong(token));
455                             } catch (Exception e) {
456                                 p.put("handles", 0l);
457                             }
458 
459                             col++;
460                         }
461                         break;
462                     }
463                 }
464                 return p;
465             }
466         } catch (IOException e) {
467 
468         }
469 
470         return null;
471     }
472 
473     /**
474      * parse a string to arguments array.
475      *
476      * @param line
477      * @return
478      */
parseCommandLine(String line)479     public static String[] parseCommandLine(String line) {
480         ArrayList<String> arguments = new ArrayList<String>();
481         StringTokenizer tokenizer = new StringTokenizer(line, "\"\' ", true);
482         int state = 0;
483         StringBuffer current = new StringBuffer();
484         while (tokenizer.hasMoreTokens()) {
485             String token = tokenizer.nextToken();
486             switch (state) {
487             case 1:
488                 if ("\'".equals(token)) {
489                     state = 3;
490                 } else {
491                     current.append(token);
492                 }
493                 break;
494             case 2:
495                 if ("\"".equals(token)) {
496                     state = 3;
497                 } else {
498                     current.append(token);
499                 }
500                 break;
501             default:
502                 if ("\'".equals(token)) {
503                     state = 1;
504                 } else if ("\"".equals(token)) {
505                     state = 2;
506                 } else if (" ".equals(token)) {
507                     if (current.length() > 0) {
508                         arguments.add(current.toString());
509                         current = new StringBuffer();
510                     }
511                 } else {
512                     current.append(token);
513                 }
514                 break;
515             }
516         }
517         if (current.length() > 0)
518             arguments.add(current.toString());
519         return arguments.toArray(new String[arguments.size()]);
520     }
521 
522     /**
523      * Get local host's IP
524      * @return
525      */
getIPAddress()526     public static String getIPAddress() {
527         try {
528             return InetAddress.getLocalHost().getHostAddress().toString();
529         } catch (UnknownHostException e) {
530             return null;
531         }
532     }
533 
534     /**
535      * Get local host name
536      * @return
537      */
getHostName()538     public static String getHostName() {
539         try {
540             return InetAddress.getLocalHost().getHostName();
541         } catch (UnknownHostException e) {
542             return null;
543         }
544 
545     }
546 
getClassesInPackage(String packageName)547     public static List<String> getClassesInPackage(String packageName) {
548         ArrayList<String> classes = new ArrayList<String>();
549         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
550         String path = packageName.replace('.', '/');
551         try {
552             Enumeration<URL> urls = classLoader.getResources(path);
553             while (urls.hasMoreElements()) {
554                 URL url = urls.nextElement();
555                 if ("file".equals(url.getProtocol())) {
556                     findClasses(packageName, new File(url.toURI()), classes);
557                 } else if ("jar".equals(url.getProtocol())) {
558                     String urlStr = url.toString();
559                     int i = urlStr.indexOf('!');
560                     if (i > 0)
561                         findClasses(packageName, new URL(urlStr.substring(4, i)), classes);
562                 }
563             }
564         } catch (Exception e) {
565             e.printStackTrace();
566         }
567 //      TreeSet classes = new TreeSet();
568 //      for (String directory : dirs) {
569 //          classes.addAll(findClasses(directory, packageName));
570 //      }
571 //      ArrayList classList = new ArrayList();
572 //      for (String clazz : classes) {
573 //          classList.add(Class.forName(clazz));
574 //      }
575 //      return classList;
576         return classes;
577     }
findClasses(String packageName, File dir, List<String> classes)578     private static void findClasses(String packageName, File dir, List<String> classes) {
579         if (!dir.isDirectory())
580             return;
581         File[] files = dir.listFiles();
582         for (File file : files) {
583             String name = file.getName();
584             if (file.isDirectory()) {
585                 findClasses(packageName + '.'+ name, file, classes);
586             }  else if (name.endsWith(".class")) {
587                 String className = packageName + '.' + name.substring(0, name.length() - 6);
588                 classes.add(className);
589             }
590         }
591     }
592 
593 
findClasses(String packageName, URL jar, List<String> classes)594     private static void findClasses(String packageName, URL jar, List<String> classes) {
595         try {
596             ZipInputStream zip = new ZipInputStream(jar.openStream());
597             ZipEntry entry;
598             while ((entry = zip.getNextEntry()) != null) {
599                 String name = entry.getName();
600                 if (name.endsWith(".class")) {
601                     name = name.replace('/', '.').substring(0, name.length() - 6);
602                     if (name.startsWith(packageName)) {
603                         classes.add(name);
604                     }
605                 }
606             }
607 
608         } catch (Exception e) {
609 
610         }
611     }
612 }
613