1 22 23 package com.izforge.izpack.util; 24 25 import java.io.File ; 26 import java.io.FileNotFoundException ; 27 import java.io.FileOutputStream ; 28 import java.io.IOException ; 29 import java.io.InputStream ; 30 import java.io.OutputStream ; 31 import java.net.URL ; 32 import java.security.CodeSource ; 33 import java.security.ProtectionDomain ; 34 import java.text.CharacterIterator ; 35 import java.text.StringCharacterIterator ; 36 import java.util.Vector ; 37 38 39 52 53 public class Librarian implements CleanupClient 54 { 55 56 60 61 private static final String JAR_PROTOCOL = "jar"; 62 63 64 private static final String FILE_PROTOCOL = "file"; 65 66 69 private static final String TEMP_LOCATION_KEY = "java.io.tmpdir"; 70 71 75 private static final String CLIENT_EXTENSION = ".class"; 76 77 78 private static final String NATIVE = "native"; 79 80 81 private static final int BLOCK_SIZE = 4096; 82 83 84 private static final float JAVA_SPECIFICATION_VERSION = Float.parseFloat(System 85 .getProperty("java.specification.version")); 86 87 91 95 private static Librarian me = null; 96 97 101 private Vector trackList = new Vector (); 102 103 107 private Vector clients = new Vector (); 108 109 114 private Vector libraryNames = new Vector (); 115 116 121 private Vector temporaryFileNames = new Vector (); 122 123 124 private String extension = ""; 125 126 127 private String nativeDirectory = NATIVE; 128 129 130 138 139 private Librarian() 140 { 141 Housekeeper.getInstance().registerForCleanup(this); 142 extension = '.' + TargetFactory.getInstance().getNativeLibraryExtension(); 143 } 144 145 146 151 152 public static Librarian getInstance() 153 { 154 if (me == null) 155 { 156 me = new Librarian(); 157 } 158 159 return (me); 160 } 161 162 163 202 203 public synchronized void loadLibrary(String name, NativeLibraryClient client) throws Exception 204 { 205 String libraryName = strip(name); 206 String tempFileName = ""; 207 208 if (loaded(libraryName)) { return; } 212 213 214 if( System.getProperty("DLL_PATH") != null ) 215 { 216 String path = System.getProperty("DLL_PATH") + "/" + name + extension; 217 path = path.replace('/', File.separatorChar); 218 Debug.trace("Try to load library " + path); 219 System.load(path); 220 return; 221 222 } 223 try 227 { 228 System.loadLibrary(libraryName); 229 return; 230 } 231 catch (UnsatisfiedLinkError exception) 232 {} 233 catch (SecurityException exception) 234 {} 235 236 Class clientClass = client.getClass(); 240 String resourceName = clientClass.getName(); 241 int nameStart = resourceName.lastIndexOf('.') + 1; 242 resourceName = resourceName.substring(nameStart, resourceName.length()) + CLIENT_EXTENSION; 243 URL url = clientClass.getResource(resourceName); 244 if (url == null) { throw (new Exception ("can't identify load protocol for " + libraryName 245 + extension)); } 246 String protocol = url.getProtocol(); 247 248 if (protocol.equalsIgnoreCase(FILE_PROTOCOL)) 252 { 253 try 254 { 255 System.load(getClientPath(name, url)); 256 } 257 catch (Throwable exception) 258 { 259 try 260 { 261 System.load(getNativePath(name, client)); 262 } 263 catch (Throwable exception2) 264 { 265 throw (new Exception ("error loading library")); 266 } 267 } 268 } 269 270 274 else if (protocol.equalsIgnoreCase(JAR_PROTOCOL)) 275 { 276 tempFileName = getTempFileName(libraryName); 277 try 278 { 279 extractFromJar(libraryName, tempFileName, client); 280 281 clients.add(client); 282 temporaryFileNames.add(tempFileName); 283 libraryNames.add(tempFileName.substring((tempFileName 284 .lastIndexOf(File.separatorChar) + 1), tempFileName.length())); 285 286 System.load(tempFileName); 290 } 291 catch (Throwable exception) 292 { 293 throw (new Exception ("error loading library\n" + exception.toString())); 294 } 295 } 296 } 297 298 299 308 309 private boolean loaded(String name) 310 { 311 if (trackList.contains(name)) 312 { 313 return (true); 314 } 315 else 316 { 317 trackList.add(name); 318 return (false); 319 } 320 } 321 322 323 330 331 private String strip(String name) 332 { 333 int extensionStart = name.lastIndexOf('.'); 334 int nameStart = name.lastIndexOf('/'); 335 if (nameStart < 0) 336 { 337 nameStart = name.lastIndexOf('\\'); 338 } 339 nameStart++; 340 341 String shortName; 342 343 if (extensionStart > 0) 344 { 345 shortName = name.substring(nameStart, extensionStart); 346 } 347 else 348 { 349 shortName = name.substring(nameStart, name.length()); 350 } 351 352 return (shortName); 353 } 354 355 356 369 370 private void extractFromJar(String name, String destination, NativeLibraryClient client) 371 throws Exception 372 { 373 int bytesRead = 0; 374 OutputStream output = null; 375 376 InputStream input = openInputStream(name, client); 380 381 try 385 { 386 output = new FileOutputStream (destination); 387 } 388 catch (FileNotFoundException exception) 389 { 390 input.close(); 391 throw (new Exception ("can't create destination file")); 392 } 393 catch (SecurityException exception) 394 { 395 input.close(); 396 throw (new Exception ("creation of destination file denied")); 397 } 398 catch (Throwable exception) 399 { 400 input.close(); 401 throw (new Exception ("unknown problem creating destination file\n" 402 + exception.toString())); 403 } 404 405 byte[] buffer = new byte[BLOCK_SIZE]; 409 try 410 { 411 do 412 { 413 bytesRead = input.read(buffer); 414 if (bytesRead > 0) 415 { 416 output.write(buffer, 0, bytesRead); 417 } 418 } 419 while (bytesRead > 0); 420 } 421 catch (Throwable exception) 422 { 423 throw (new Exception ("error writing to destination file\n" + exception.toString())); 424 } 425 426 finally 430 { 431 input.close(); 432 output.flush(); 433 output.close(); 434 } 435 } 436 437 438 447 448 private String getClientPath(String name, URL clientURL) 449 { 450 String path = clientURL.getFile(); 451 452 int nameStart = path.lastIndexOf('/') + 1; 453 454 path = path.substring(0, nameStart); 455 path = path + name + extension; 456 path = path.replace('/', File.separatorChar); 457 path = revisePath(path); 461 462 return (path); 463 } 464 465 466 475 476 private String getNativePath(String name, NativeLibraryClient client) 477 { 478 ProtectionDomain domain = client.getClass().getProtectionDomain(); 479 CodeSource codeSource = domain.getCodeSource(); 480 URL url = codeSource.getLocation(); 481 String path = url.getPath(); 482 path = path + nativeDirectory + '/' + name + extension; 483 path = path.replace('/', File.separatorChar); 484 path = revisePath(path); 488 489 return (path); 490 } 491 492 493 500 501 private String revisePath(String in) 502 { 503 505 StringBuffer sb = new StringBuffer (); 506 CharacterIterator iter = new StringCharacterIterator (in); 507 for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) 508 { 509 if (c == '%') 510 { 511 char c1 = iter.next(); 512 if (c1 != CharacterIterator.DONE) 513 { 514 int i1 = Character.digit(c1, 16); 515 char c2 = iter.next(); 516 if (c2 != CharacterIterator.DONE) 517 { 518 int i2 = Character.digit(c2, 16); 519 sb.append((char) ((i1 << 4) + i2)); 520 } 521 } 522 } 523 else 524 { 525 sb.append(c); 526 } 527 } 528 String path = sb.toString(); 529 return path; 530 } 531 532 533 543 544 private InputStream openInputStream(String name, NativeLibraryClient client) throws Exception 545 { 546 Class clientClass = client.getClass(); 547 InputStream input = clientClass.getResourceAsStream(name + extension); 552 553 if (input == null) 559 { 560 input = clientClass.getResourceAsStream('/' + nativeDirectory + '/' + name + extension); 561 } 562 563 if (input == null) 567 { 568 throw (new Exception ("can't locate library")); 569 } 570 else 571 { 572 return (input); 573 } 574 } 575 576 577 585 586 594 private String getTempFileName(String name) 595 { 596 StringBuffer fileName = new StringBuffer (); 597 String path = System.getProperty(TEMP_LOCATION_KEY); 598 if (path.charAt(path.length() - 1) == File.separatorChar) 599 { 600 path = path.substring(0, (path.length() - 1)); 601 } 602 String modifier = ""; 603 int counter = 0; 604 File file = null; 605 606 do 607 { 608 fileName.delete(0, fileName.length()); 609 fileName.append(path); 610 fileName.append(File.separatorChar); 611 fileName.append(name); 612 fileName.append(modifier); 613 fileName.append(extension); 614 615 modifier = Integer.toString(counter); 616 counter++; 617 618 file = new File (fileName.toString()); 619 } 620 while (file.exists()); 621 622 return (fileName.toString()); 623 } 624 625 626 634 635 public void setNativeDirectory(String directory) 636 { 637 if (directory == null) 638 { 639 nativeDirectory = ""; 640 } 641 else 642 { 643 nativeDirectory = directory; 644 } 645 } 646 647 648 664 665 public void cleanUp() 666 { 667 if (JAVA_SPECIFICATION_VERSION < 1.5) 668 oldCleanUp(); 669 else 670 newCleanUp(); 671 672 } 673 674 675 683 684 private void oldCleanUp() 685 { 686 for (int i = 0; i < clients.size(); i++) 687 { 688 NativeLibraryClient client = (NativeLibraryClient) clients.elementAt(i); 692 String libraryName = (String ) libraryNames.elementAt(i); 693 694 FreeThread free = new FreeThread(libraryName, client); 695 free.start(); 696 try 697 { 698 free.join(50); 701 } 702 catch (Throwable exception) 703 {} 705 String tempFileName = (String ) temporaryFileNames.elementAt(i); 709 try 710 { 711 File file = new File (tempFileName); 712 file.delete(); 713 } 714 catch (Throwable exception) 715 {} } 717 } 718 719 720 726 727 private void newCleanUp() 728 { 729 733 try 734 { 735 LibraryRemover.invoke(temporaryFileNames); 736 } 737 catch (IOException e1) 738 { 739 e1.printStackTrace(); 741 } 742 743 } 744 } 745 746 | Popular Tags |