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 getOSName()100 public static String getOSName() { 101 return osName; 102 } 103 getOSVersion()104 public static String getOSVersion() { 105 return osVersion; 106 } 107 getOSArch()108 public static String getOSArch() { 109 return osArch; 110 } 111 112 /** 113 * Set the contents of the clipboard to the provided text 114 */ setClipboardText(String s)115 public static void setClipboardText(String s) { 116 StringSelection ss = new StringSelection(s); 117 118 // if (OS.get() == OS.MACOSX) { 119 // // workaround MAC OS X has a bug. After setting a text into 120 // clipboard, the java program will not 121 // // receive the data written by other apllications. 122 // File file = null; 123 // try { 124 // file = File.createTempFile("SystemUtil", "SystemUtil"); 125 // FileUtil.writeStringToFile(file.getAbsolutePath(), s); 126 // if (exec("pbcopy < \""+ file.getAbsolutePath() + "\"", false) == 0) 127 // return; 128 // } catch (IOException e) { 129 // // TODO Auto-generated catch block 130 // e.printStackTrace(); 131 // } finally { 132 // if (file != null) 133 // file.delete(); 134 // } 135 // 136 // } 137 // 138 sysClipboard.setContents(ss, ss); 139 } 140 141 /** 142 * Get plain text from clipboard 143 * 144 * @return 145 */ getClipboardText()146 public static String getClipboardText() { 147 Transferable contents = getTransferable(); 148 if (contents == null || !contents.isDataFlavorSupported(DataFlavor.stringFlavor)) 149 return ""; 150 try { 151 return (String) contents.getTransferData(DataFlavor.stringFlavor); 152 } catch (Exception ex) { 153 return ""; 154 } 155 } 156 getTransferable()157 private static Transferable getTransferable() { 158 // To avoid IllegalStateException, we try 25 times to access clipboard. 159 for (int i = 0; i < 25; i++) { 160 try { 161 return sysClipboard.getContents(null); 162 } catch (IllegalStateException e) { 163 try { 164 Thread.sleep(200); 165 } catch (InterruptedException e1) { 166 } 167 } 168 } 169 throw new RuntimeException("System Clipboard is not ready"); 170 } 171 172 /** 173 * Execute a script and waiting it for finishing 174 * 175 * @param content 176 * @return 177 */ execScript(String content)178 public static int execScript(String content) { 179 StringBuffer output = new StringBuffer(); 180 int code = execScript(content, output, output); 181 LOG.info(content + "\n" + "Exit Code: " + code + "\n" + output); 182 return code; 183 } 184 185 /** 186 * Execute a script and waiting it for finishing 187 * @param content 188 * @param output 189 * @param error 190 * @return 191 */ execScript(String content, StringBuffer output, StringBuffer error)192 public static int execScript(String content, StringBuffer output, StringBuffer error) { 193 File file = null; 194 try { 195 file = FileUtil.getUniqueFile(SCRIPT_TEMP_DIR, "tempscript", ".bat"); 196 FileUtil.writeStringToFile(file.getAbsolutePath(), content); 197 String[] cmd; 198 if (isWindows()) 199 cmd = new String[] { file.getAbsolutePath() }; 200 else 201 cmd = new String[] { "sh", file.getAbsolutePath() }; 202 return exec(cmd, null, null, output, error); 203 } catch (Exception e) { 204 return -1; 205 } finally { 206 if (file != null && !file.delete()) 207 file.deleteOnExit(); 208 } 209 } 210 211 /** 212 * Start a background process 213 * @param cmd 214 * @param env 215 * @param dir 216 * @param output 217 * @param error 218 * @return 219 */ backgroundExec(String[] cmd, String[] env, File dir, StringBuffer output, StringBuffer error)220 public static Process backgroundExec(String[] cmd, String[] env, File dir, StringBuffer output, StringBuffer error) { 221 try { 222 Process process = Runtime.getRuntime().exec(cmd, env, dir); 223 StreamPump inputPump = new StreamPump(output, process.getInputStream()); 224 StreamPump errorPump = new StreamPump(error, process.getErrorStream()); 225 inputPump.start(); 226 errorPump.start(); 227 return process; 228 } catch (Exception e) { 229 return null; 230 } 231 } 232 233 /** 234 * Execute the command and wait for its finishing 235 * @param cmd 236 * @param env 237 * @param dir 238 * @param output 239 * @param error 240 * @return 241 */ exec(String[] cmd, String[] env, File dir, StringBuffer output, StringBuffer error)242 public static int exec(String[] cmd, String[] env, File dir, StringBuffer output, StringBuffer error) { 243 Process process = null; 244 try { 245 LOG.log(Level.FINE, "exec: " + Arrays.toString(cmd)); 246 process = Runtime.getRuntime().exec(cmd, env, dir); 247 } catch (Exception e) { 248 e.printStackTrace(); 249 return -1; 250 } 251 252 StreamPump inputPump = new StreamPump(output, process.getInputStream()); 253 StreamPump errorPump = new StreamPump(error, process.getErrorStream()); 254 inputPump.start(); 255 errorPump.start(); 256 257 try { 258 int code = process.waitFor(); 259 inputPump.join(); 260 errorPump.join(); 261 return code; 262 } catch (InterruptedException e) { 263 return -2; 264 } 265 } 266 exec(String[] cmd, StringBuffer output)267 public static int exec(String[] cmd, StringBuffer output) { 268 return exec(cmd, null, null, output, output); 269 } 270 271 /** 272 * Make the current thread sleep some seconds. 273 * 274 * @param second 275 */ sleep(double second)276 public static void sleep(double second) { 277 try { 278 if (second > 0) 279 Thread.sleep((long) (second * 1000)); 280 } catch (InterruptedException e) { 281 } 282 } 283 284 /** 285 * Get Information of running processes 286 * 287 */ getProcesses()288 public static List<HashMap<String, Object>> getProcesses() { 289 List<HashMap<String, Object>> ret = new ArrayList<HashMap<String, Object>>(); 290 try { 291 StringBuffer output = new StringBuffer(); 292 if (isWindows()) { 293 File file = new File(SCRIPT_TEMP_DIR, "ps.vbs"); 294 // if (!file.exists()) { 295 String contents = "Set wmi=GetObject(\"Winmgmts:\")\n\r" 296 + "Set ps = wmi.ExecQuery(\"Select * from Win32_Process\")\n\r" 297 + "WScript.Echo \"PID COMMAND\" \n\r" 298 + "For Each p in ps\n\r" 299 + "WScript.Echo p.ProcessId & \" \" & p.CommandLine\n\r" 300 + "Next"; 301 FileUtil.writeStringToFile(file.getAbsolutePath(), contents); 302 // } 303 exec(new String[] { "cscript", "//Nologo", file.getAbsolutePath()}, null, null, output, output); 304 } else { 305 exec(new String[] {"ps", "-eo", "pid,command"}, null, null, output, output); 306 } 307 308 BufferedReader reader = new BufferedReader(new StringReader(output.toString())); 309 String line = null; 310 reader.readLine(); 311 while ((line = reader.readLine()) != null) { 312 HashMap<String, Object> p = new HashMap<String, Object>(); 313 StringTokenizer tokenizer = new StringTokenizer(line, " ", true); 314 StringBuffer last = new StringBuffer(); 315 int col = 0; 316 while (tokenizer.hasMoreTokens()) { 317 String token = tokenizer.nextToken(); 318 switch (col) { 319 case 0: 320 if (!" ".equals(token)) { 321 // 322 p.put("pid", token); 323 col++; 324 } 325 break; 326 default: 327 last.append(token); 328 break; 329 } 330 } 331 332 p.put("command", last.toString().trim()); 333 ret.add(p); 334 } 335 } catch (IOException e) { 336 337 } 338 339 return ret; 340 } 341 killProcess(String pattern)342 public static void killProcess(String pattern) { 343 List<HashMap<String, Object>> processes = SystemUtil.getProcesses(); 344 for (HashMap<String, Object> p : processes) { 345 String command = (String) p.get("command"); 346 String pid = (String) p.get("pid"); 347 if (command != null && command.matches(pattern)) { 348 if (isWindows()) { 349 exec(new String[] { "taskkill", "/F", "/PID", pid }, null, null, null, null); 350 } else { 351 exec(new String[] { "kill", "-9", pid }, null, null, null, null); 352 } 353 } 354 } 355 } 356 hasProcess(String pattern)357 public static boolean hasProcess(String pattern) { 358 return findProcess(pattern) != null; 359 } 360 findProcess(String pattern)361 public static HashMap<String, Object> findProcess(String pattern) { 362 List<HashMap<String, Object>> processes = SystemUtil.getProcesses(); 363 for (HashMap<String, Object> p : processes) { 364 String command = (String) p.get("command"); 365 if (command != null && command.matches(pattern)) { 366 return p; 367 } 368 } 369 370 return null; 371 } 372 findProcesses(String pattern)373 public static List<HashMap<String, Object>> findProcesses(String pattern) { 374 List<HashMap<String, Object>> result = new ArrayList<HashMap<String, Object>>(); 375 List<HashMap<String, Object>> processes = SystemUtil.getProcesses(); 376 for (HashMap<String, Object> p : processes) { 377 String command = (String) p.get("command"); 378 if (command != null && command.matches(pattern)) { 379 result.add(p); 380 } 381 } 382 383 return result; 384 } 385 386 /** 387 * Get Information of running processes 388 * 389 */ getProcessPerfData(String processId)390 public static HashMap<String, Object> getProcessPerfData(String processId) { 391 try { 392 StringBuffer output = new StringBuffer(); 393 if (isWindows()) { 394 File file = new File(SCRIPT_TEMP_DIR, "pps.vbs"); 395 String contents = "Set wmi=GetObject(\"Winmgmts:\")\n\r" 396 + "Set pps = wmi.ExecQuery(\"Select * from Win32_PerfFormattedData_PerfProc_Process Where IDProcess='" + processId+"'\")\n\r" 397 + "WScript.Echo \"pcpu PrivateBytes WorkingSet HandleCount\" \n\r" 398 + "For Each pp in pps \n\r" 399 + "WScript.Echo pp.PercentProcessorTime & \" \" & Round(pp.PrivateBytes/1024) & \" \" & Round(pp.WorkingSet/1024) & \" \" & pp.HandleCount \n\r" 400 + "Next"; 401 // String contents = "var wmi = GetObject(\"Winmgmts:\");\n" 402 // + "var pps = new Enumerator(wmi.ExecQuery(\"Select * from Win32_PerfFormattedData_PerfProc_Process Where IDProcess='" + processId+"'\"));\n" 403 // + "WScript.Echo(\"pcpu rss\");\n" 404 // + "for ( ; !pps.atEnd(); pps.moveNext()) {\n" 405 // + "var pp = pps.item();\n" 406 // + "WScript.Echo(pp.PercentProcessorTime + \" \" + (pp.WorkingSet/1024));\n" 407 // + "}"; 408 FileUtil.writeStringToFile(file.getAbsolutePath(), contents); 409 exec(new String[] { "cscript", "//Nologo", file.getAbsolutePath()}, null, null, output, output); 410 } else { 411 exec(new String[] {"ps", "-p", processId ,"-o", "pcpu,vsz,rss,tty"}, null, null, output, output); 412 } 413 BufferedReader reader = new BufferedReader(new StringReader(output.toString())); 414 String line = null; 415 reader.readLine(); 416 if ((line = reader.readLine()) != null) { 417 HashMap<String, Object> p = new HashMap<String, Object>(); 418 StringTokenizer tokenizer = new StringTokenizer(line, " ", true); 419 int col = 0; 420 while (tokenizer.hasMoreTokens()) { 421 String token = tokenizer.nextToken(); 422 switch (col) { 423 case 0: 424 if (!" ".equals(token)) { 425 // 426 p.put("pcpu", Double.parseDouble(token)); 427 col++; 428 } 429 break; 430 case 1: 431 if (!" ".equals(token)) { 432 // 433 p.put("vsz", Long.parseLong(token)); 434 col++; 435 } 436 break; 437 case 2: 438 if (!" ".equals(token)) { 439 // 440 p.put("rss", Long.parseLong(token)); 441 col++; 442 } 443 break; 444 case 3: 445 if (!" ".equals(token)) { 446 // 447 try { 448 p.put("handles", Long.parseLong(token)); 449 } catch (Exception e) { 450 p.put("handles", 0l); 451 } 452 453 col++; 454 } 455 break; 456 } 457 } 458 return p; 459 } 460 } catch (IOException e) { 461 462 } 463 464 return null; 465 } 466 467 /** 468 * parse a string to arguments array. 469 * 470 * @param line 471 * @return 472 */ parseCommandLine(String line)473 public static String[] parseCommandLine(String line) { 474 ArrayList<String> arguments = new ArrayList<String>(); 475 StringTokenizer tokenizer = new StringTokenizer(line, "\"\' ", true); 476 int state = 0; 477 StringBuffer current = new StringBuffer(); 478 while (tokenizer.hasMoreTokens()) { 479 String token = tokenizer.nextToken(); 480 switch (state) { 481 case 1: 482 if ("\'".equals(token)) { 483 state = 3; 484 } else { 485 current.append(token); 486 } 487 break; 488 case 2: 489 if ("\"".equals(token)) { 490 state = 3; 491 } else { 492 current.append(token); 493 } 494 break; 495 default: 496 if ("\'".equals(token)) { 497 state = 1; 498 } else if ("\"".equals(token)) { 499 state = 2; 500 } else if (" ".equals(token)) { 501 if (current.length() > 0) { 502 arguments.add(current.toString()); 503 current = new StringBuffer(); 504 } 505 } else { 506 current.append(token); 507 } 508 break; 509 } 510 } 511 if (current.length() > 0) 512 arguments.add(current.toString()); 513 return arguments.toArray(new String[arguments.size()]); 514 } 515 516 /** 517 * Get local host's IP 518 * @return 519 */ getIPAddress()520 public static String getIPAddress() { 521 try { 522 return InetAddress.getLocalHost().getHostAddress().toString(); 523 } catch (UnknownHostException e) { 524 return null; 525 } 526 } 527 528 /** 529 * Get local host name 530 * @return 531 */ getHostName()532 public static String getHostName() { 533 try { 534 return InetAddress.getLocalHost().getHostName(); 535 } catch (UnknownHostException e) { 536 return null; 537 } 538 539 } 540 getClassesInPackage(String packageName)541 public static List<String> getClassesInPackage(String packageName) { 542 ArrayList<String> classes = new ArrayList<String>(); 543 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 544 String path = packageName.replace('.', '/'); 545 try { 546 Enumeration<URL> urls = classLoader.getResources(path); 547 while (urls.hasMoreElements()) { 548 URL url = urls.nextElement(); 549 if ("file".equals(url.getProtocol())) { 550 findClasses(packageName, new File(url.toURI()), classes); 551 } else if ("jar".equals(url.getProtocol())) { 552 String urlStr = url.toString(); 553 int i = urlStr.indexOf('!'); 554 if (i > 0) 555 findClasses(packageName, new URL(urlStr.substring(4, i)), classes); 556 } 557 } 558 } catch (Exception e) { 559 e.printStackTrace(); 560 } 561 // TreeSet classes = new TreeSet(); 562 // for (String directory : dirs) { 563 // classes.addAll(findClasses(directory, packageName)); 564 // } 565 // ArrayList classList = new ArrayList(); 566 // for (String clazz : classes) { 567 // classList.add(Class.forName(clazz)); 568 // } 569 // return classList; 570 return classes; 571 } findClasses(String packageName, File dir, List<String> classes)572 private static void findClasses(String packageName, File dir, List<String> classes) { 573 if (!dir.isDirectory()) 574 return; 575 File[] files = dir.listFiles(); 576 for (File file : files) { 577 String name = file.getName(); 578 if (file.isDirectory()) { 579 findClasses(packageName + '.'+ name, file, classes); 580 } else if (name.endsWith(".class")) { 581 String className = packageName + '.' + name.substring(0, name.length() - 6); 582 classes.add(className); 583 } 584 } 585 } 586 587 findClasses(String packageName, URL jar, List<String> classes)588 private static void findClasses(String packageName, URL jar, List<String> classes) { 589 try { 590 ZipInputStream zip = new ZipInputStream(jar.openStream()); 591 ZipEntry entry; 592 while ((entry = zip.getNextEntry()) != null) { 593 String name = entry.getName(); 594 if (name.endsWith(".class")) { 595 name = name.replace('/', '.').substring(0, name.length() - 6); 596 if (name.startsWith(packageName)) { 597 classes.add(name); 598 } 599 } 600 } 601 602 } catch (Exception e) { 603 604 } 605 } 606 } 607