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