| 1 19 package com.izforge.izpack.util; 20 21 import java.util.List ; 22 import java.io.BufferedOutputStream ; 23 import java.io.BufferedReader ; 24 import java.io.BufferedWriter ; 25 import java.io.File ; 26 import java.io.FileInputStream ; 27 import java.io.FileOutputStream ; 28 import java.io.IOException ; 29 import java.io.InputStream ; 30 import java.io.InputStreamReader ; 31 import java.io.OutputStream ; 32 import java.io.OutputStreamWriter ; 33 import java.io.PrintStream ; 34 import java.io.PrintWriter ; 35 import java.text.SimpleDateFormat ; 36 import java.util.ArrayList ; 37 import java.util.Collections ; 38 import java.util.Date ; 39 import java.util.Iterator ; 40 import java.util.TreeSet ; 41 42 58 public class LibraryRemover 59 { 60 61 66 private static final String [] SANDBOX_CONTENT = { "com/izforge/izpack/util/LibraryRemover.class"}; 67 68 69 private static final String BASE_KEY = "lib.rem.base"; 70 71 72 private static final String PHASE_KEY = "self.mod.phase"; 73 74 75 private static final String JAVA_HOME = System.getProperty("java.home"); 76 77 78 private static final String PREFIX = "InstallRemover"; 79 80 81 private int phase = 0; 82 83 84 private File logFile = null; 85 86 87 private File sandbox = null; 88 89 90 private File specFile = null; 91 92 93 private SimpleDateFormat isoPoint = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss.SSS"); 94 95 96 private Date date = new Date (); 97 98 104 private LibraryRemover(int phase) throws IOException  105 { 106 this.phase = phase; 107 if (phase == 1) 108 { 109 initJavaExec(); 110 } 111 else 112 { 113 logFile = new File (System.getProperty(BASE_KEY) + ".log"); 114 specFile = new File (System.getProperty(BASE_KEY) + ".spec"); 115 sandbox = new File (System.getProperty(BASE_KEY) + ".d"); 116 } 117 } 118 119 125 public static void invoke(List temporaryFileNames) throws IOException  126 { 127 LibraryRemover self = new LibraryRemover(1); 128 self.invoke1(temporaryFileNames); 129 } 130 131 138 private void initJavaExec() throws IOException  139 { 140 try 141 { 142 Process p = Runtime.getRuntime().exec(javaCommand()); 143 144 new StreamProxy(p.getErrorStream(), "err").start(); 145 new StreamProxy(p.getInputStream(), "out").start(); 146 p.getOutputStream().close(); 147 148 p.waitFor(); 150 } 151 catch (InterruptedException ie) 152 { 153 throw new IOException ("Unable to create a java subprocess"); 154 } 155 } 156 157 163 private void invoke1(List temporaryFileNames) throws IOException  164 { 165 while (true) 167 { 168 logFile = File.createTempFile(PREFIX, ".log"); 169 String f = logFile.getCanonicalPath(); 170 specFile = new File (f.substring(0, f.length() - 4) + ".spec"); 171 sandbox = new File (f.substring(0, f.length() - 4) + ".d"); 172 173 if (!sandbox.exists()) break; 175 176 logFile.delete(); 177 } 178 if (!sandbox.mkdir()) throw new RuntimeException ("Failed to create temp dir: " + sandbox); 179 180 sandbox = sandbox.getCanonicalFile(); 181 logFile = logFile.getCanonicalFile(); 182 OutputStream out = null; 183 InputStream in = null; 184 byte[] buf = new byte[5120]; 185 int extracted = 0; 186 for (int i = 0; i < SANDBOX_CONTENT.length; ++i) 191 { 192 in = getClass().getResourceAsStream("/" + SANDBOX_CONTENT[i]); 193 194 File outFile = new File (sandbox, SANDBOX_CONTENT[i]); 195 File parent = outFile.getParentFile(); 196 if (parent != null && !parent.exists()) parent.mkdirs(); 197 198 out = new BufferedOutputStream (new FileOutputStream (outFile)); 199 200 int n; 201 while ((n = in.read(buf, 0, buf.length)) > 0) 202 out.write(buf, 0, n); 203 204 out.close(); 205 extracted++; 206 207 } 208 out = new BufferedOutputStream (new FileOutputStream (specFile)); 210 BufferedWriter specWriter = new BufferedWriter (new OutputStreamWriter (out)); 211 Iterator iter = temporaryFileNames.iterator(); 212 while (iter.hasNext()) 213 { 214 specWriter.write((String ) iter.next()); 215 if (iter.hasNext()) specWriter.newLine(); 216 } 217 specWriter.flush(); 218 out.close(); 219 220 spawn(2); 221 222 log("Exit"); 224 System.exit(0); 225 } 226 227 233 private ArrayList getFilesList() throws Exception  234 { 235 TreeSet files = new TreeSet (Collections.reverseOrder()); 237 InputStream in = new FileInputStream (specFile); 238 InputStreamReader inReader = new InputStreamReader (in); 239 BufferedReader reader = new BufferedReader (inReader); 240 241 String read = reader.readLine(); 243 while (read != null) 244 { 245 files.add(new File (read)); 246 read = reader.readLine(); 247 } 248 in.close(); 249 return new ArrayList (files); 251 } 252 253 256 private void invoke2() 257 { 258 259 try 260 { 261 try 263 { 264 Thread.sleep(1000); 265 } 266 catch (Exception x) 267 {} 268 269 ArrayList files = getFilesList(); 270 int size = files.size(); 271 273 log("deleteing temporary dlls/shls"); 274 for (int i = 0; i < size; i++) 275 { 276 File file = (File ) files.get(i); 277 file.delete(); 278 if (file.exists()) 279 log(" deleting of " + file.getCanonicalPath() + " failed!!!"); 280 else 281 log(" " + file.getCanonicalPath()); 282 283 } 284 285 log("deleteing sandbox"); 287 deleteTree(sandbox); 288 specFile.delete(); 289 } 290 catch (Exception e) 291 { 292 log(e); 293 } 294 } 295 296 303 private Process spawn(int nextPhase) throws IOException  304 { 305 String base = logFile.getAbsolutePath(); 306 base = base.substring(0, base.length() - 4); 307 308 String [] javaCmd = new String [] { javaCommand(), "-classpath", sandbox.getAbsolutePath(), 311 "-D" + BASE_KEY + "=" + base, "-D" + PHASE_KEY + "=" + nextPhase, 312 getClass().getName()}; 313 314 StringBuffer sb = new StringBuffer ("Spawning phase "); 315 sb.append(nextPhase).append(": "); 316 for (int i = 0; i < javaCmd.length; i++) 317 sb.append("\n\t").append(javaCmd[i]); 318 log(sb.toString()); 319 320 return Runtime.getRuntime().exec(javaCmd, null, null); } 323 324 330 public static boolean deleteTree(File file) 331 { 332 if (file.isDirectory()) 333 { 334 File [] files = file.listFiles(); 335 for (int i = 0; i < files.length; i++) 336 deleteTree(files[i]); 337 } 338 return file.delete(); 339 } 340 341 346 private static String addExtension(String command) 347 { 348 return command + (OsVersion.IS_WINDOWS || OsVersion.IS_OS2 ? ".exe" : ""); 351 } 352 353 358 private static String javaCommand() 359 { 360 String executable = addExtension("java"); 361 String dir = new File (JAVA_HOME + "/bin").getAbsolutePath(); 362 File jExecutable = new File (dir, executable); 363 364 if (!jExecutable.exists()) return executable; 368 return jExecutable.getAbsolutePath(); 369 } 370 371 public static void main(String [] args) 372 { 373 378 try 379 { 380 LibraryRemover librianRemover = new LibraryRemover(2); 382 librianRemover.invoke2(); 383 } 384 catch (IOException ioe) 385 { 386 System.err.println("Error invoking a secondary phase"); 387 System.err.println("Note that this program is only intended as a secondary process"); 388 ioe.printStackTrace(); 389 } 390 } 391 392 397 398 PrintStream log = null; 399 400 private PrintStream checkLog() 401 { 402 try 403 { 404 if (log == null) log = new PrintStream (new FileOutputStream (logFile.toString(), true)); 405 } 406 catch (IOException x) 407 { 408 System.err.println("Phase " + phase + " log err: " + x.getMessage()); 409 x.printStackTrace(); 410 } 411 date.setTime(System.currentTimeMillis()); 412 return log; 413 } 414 415 private void log(Throwable t) 416 { 417 if (checkLog() != null) 418 { 419 log.println(isoPoint.format(date) + " Phase " + phase + ": " + t.getMessage()); 420 t.printStackTrace(log); 421 } 422 } 423 424 private void log(String msg) 425 { 426 if (checkLog() != null) 427 log.println(isoPoint.format(date) + " Phase " + phase + ": " + msg); 428 } 429 430 public static class StreamProxy extends Thread  431 { 432 433 InputStream in; 434 435 String name; 436 437 OutputStream out; 438 439 public StreamProxy(InputStream in, String name) 440 { 441 this(in, name, null); 442 } 443 444 public StreamProxy(InputStream in, String name, OutputStream out) 445 { 446 this.in = in; 447 this.name = name; 448 this.out = out; 449 } 450 451 public void run() 452 { 453 try 454 { 455 PrintWriter pw = null; 456 if (out != null) pw = new PrintWriter (out); 457 458 BufferedReader br = new BufferedReader (new InputStreamReader (in)); 459 String line; 460 while ((line = br.readLine()) != null) 461 { 462 if (pw != null) pw.println(line); 463 } 465 if (pw != null) pw.flush(); 466 } 467 catch (IOException ioe) 468 { 469 ioe.printStackTrace(); 470 } 471 } 472 } 473 474 } 475 | Popular Tags |