1 36 package org.ungoverned.oscar.util; 37 38 import java.io.*; 39 import java.security.AccessController ; 40 import java.security.PrivilegedActionException ; 41 import java.security.PrivilegedExceptionAction ; 42 import java.util.*; 43 import java.util.jar.JarFile ; 44 import java.util.jar.Manifest ; 45 import java.util.zip.ZipEntry ; 46 47 import org.osgi.framework.Bundle; 48 import org.osgi.framework.BundleActivator; 49 import org.ungoverned.oscar.BundleArchive; 50 import org.ungoverned.oscar.Oscar; 51 52 59 public class DefaultBundleArchive implements BundleArchive 60 { 61 private static final transient String BUNDLE_JAR_FILE = "bundle.jar"; 62 private static final transient String BUNDLE_LOCATION_FILE = "bundle.location"; 63 private static final transient String BUNDLE_STATE_FILE = "bundle.state"; 64 private static final transient String BUNDLE_START_LEVEL_FILE = "bundle.startlevel"; 65 private static final transient String REFRESH_COUNTER_FILE = "refresh.counter"; 66 private static final transient String BUNDLE_ACTIVATOR_FILE = "bundle.activator"; 67 68 private static final transient String REVISION_DIRECTORY = "version"; 69 private static final transient String EMBEDDED_DIRECTORY = "embedded"; 70 private static final transient String LIBRARY_DIRECTORY = "lib"; 71 private static final transient String DATA_DIRECTORY = "data"; 72 73 private static final transient String ACTIVE_STATE = "active"; 74 private static final transient String INSTALLED_STATE = "installed"; 75 private static final transient String UNINSTALLED_STATE = "uninstalled"; 76 77 private long m_id = -1; 78 private File m_dir = null; 79 private String m_location = null; 80 private int m_persistentState = -1; 81 private int m_startLevel = -1; 82 private Map m_currentHeader = null; 83 84 private long m_refreshCount = -1; 85 private int m_revisionCount = -1; 86 87 public DefaultBundleArchive(File dir, long id, String location, InputStream is) 88 throws Exception 89 { 90 this(dir, id); 91 m_location = location; 92 93 try 95 { 96 initialize(is); 97 } 98 catch (Exception ex) 99 { 100 if (!deleteDirectoryTree(dir)) 101 { 102 Oscar.error("Unable to delete the archive directory."); 103 } 104 throw ex; 105 } 106 } 107 108 public DefaultBundleArchive(File dir, long id) 109 { 110 m_dir = dir; 111 m_id = id; 112 if (m_id <= 0) 113 { 114 throw new IllegalArgumentException ( 115 "Bundle ID cannot be less than or equal to zero."); 116 } 117 } 118 119 private void initialize(InputStream is) 120 throws Exception 121 { 122 if (System.getSecurityManager() != null) 123 { 124 try 125 { 126 AccessController.doPrivileged( 127 new PrivilegedAction( 128 PrivilegedAction.INITIALIZE_ACTION, this, is)); 129 } 130 catch (PrivilegedActionException ex) 131 { 132 throw ((PrivilegedActionException ) ex).getException(); 133 } 134 } 135 else 136 { 137 initializeUnchecked(is); 138 } 139 } 140 141 private void initializeUnchecked(InputStream is) 142 throws Exception 143 { 144 FileWriter fw = null; 145 BufferedWriter bw = null; 146 147 try 148 { 149 if (!m_dir.mkdir()) 151 { 152 Oscar.error("DefaultBundleArchive: Unable to create archive directory."); 153 throw new IOException("Unable to create archive directory."); 154 } 155 156 File file = new File (m_dir, BUNDLE_LOCATION_FILE); 158 fw = new FileWriter(file); 159 bw = new BufferedWriter(fw); 160 bw.write(m_location, 0, m_location.length()); 161 162 File revisionDir = new File (m_dir, REVISION_DIRECTORY + "0.0"); 167 if (!revisionDir.mkdir()) 168 { 169 Oscar.error("DefaultBundleArchive: Unable to create revision directory."); 170 throw new IOException("Unable to create revision directory."); 171 } 172 173 file = new File (revisionDir, BUNDLE_JAR_FILE); 175 copy(is, file); 176 177 preprocessBundleJar(0, revisionDir); 179 180 } 181 finally 182 { 183 if (is != null) is.close(); 184 if (bw != null) bw.close(); 185 if (fw != null) fw.close(); 186 } 187 } 188 189 public File getDirectory() 190 { 191 return m_dir; 192 } 193 194 public long getId() 195 { 196 return m_id; 197 } 198 199 public String getLocation() 200 throws Exception 201 { 202 if (m_location != null) 203 { 204 return m_location; 205 } 206 else if (System.getSecurityManager() != null) 207 { 208 try 209 { 210 return (String ) AccessController.doPrivileged( 211 new PrivilegedAction( 212 PrivilegedAction.GET_LOCATION_ACTION, this)); 213 } 214 catch (PrivilegedActionException ex) 215 { 216 throw ((PrivilegedActionException ) ex).getException(); 217 } 218 } 219 else 220 { 221 return getLocationUnchecked(); 222 } 223 } 224 225 private String getLocationUnchecked() 226 throws Exception 227 { 228 File locFile = new File (m_dir, BUNDLE_LOCATION_FILE); 230 231 FileReader fr = null; 233 BufferedReader br = null; 234 try 235 { 236 fr = new FileReader(locFile); 237 br = new BufferedReader(fr); 238 m_location = br.readLine(); 239 return m_location; 240 } 241 finally 242 { 243 if (br != null) br.close(); 244 if (fr != null) fr.close(); 245 } 246 } 247 248 public int getPersistentState() 249 throws Exception 250 { 251 if (m_persistentState >= 0) 252 { 253 return m_persistentState; 254 } 255 else if (System.getSecurityManager() != null) 256 { 257 try 258 { 259 return ((Integer ) AccessController.doPrivileged( 260 new PrivilegedAction( 261 PrivilegedAction.GET_PERSISTENT_STATE_ACTION, this))).intValue(); 262 } 263 catch (PrivilegedActionException ex) 264 { 265 throw ((PrivilegedActionException ) ex).getException(); 266 } 267 } 268 else 269 { 270 return getPersistentStateUnchecked(); 271 } 272 } 273 274 private int getPersistentStateUnchecked() 275 throws Exception 276 { 277 File stateFile = new File (m_dir, BUNDLE_STATE_FILE); 279 280 if (!stateFile.exists()) 283 { 284 return Bundle.INSTALLED; 285 } 286 287 FileReader fr = null; 289 BufferedReader br= null; 290 try 291 { 292 fr = new FileReader(stateFile); 293 br = new BufferedReader(fr); 294 String s = br.readLine(); 295 if (s.equals(ACTIVE_STATE)) 296 { 297 m_persistentState = Bundle.ACTIVE; 298 } 299 else if (s.equals(UNINSTALLED_STATE)) 300 { 301 m_persistentState = Bundle.UNINSTALLED; 302 } 303 else 304 { 305 m_persistentState = Bundle.INSTALLED; 306 } 307 return m_persistentState; 308 } 309 finally 310 { 311 if (br != null) br.close(); 312 if (fr != null) fr.close(); 313 } 314 } 315 316 public void setPersistentState(int state) 317 throws Exception 318 { 319 if (System.getSecurityManager() != null) 320 { 321 try 322 { 323 AccessController.doPrivileged( 324 new PrivilegedAction( 325 PrivilegedAction.SET_PERSISTENT_STATE_ACTION, this, state)); 326 } 327 catch (PrivilegedActionException ex) 328 { 329 throw ((PrivilegedActionException ) ex).getException(); 330 } 331 } 332 else 333 { 334 setPersistentStateUnchecked(state); 335 } 336 } 337 338 private void setPersistentStateUnchecked(int state) 339 throws Exception 340 { 341 File stateFile = new File (m_dir, BUNDLE_STATE_FILE); 343 344 FileWriter fw = null; 346 BufferedWriter bw= null; 347 try 348 { 349 fw = new FileWriter(stateFile); 350 bw = new BufferedWriter(fw); 351 String s = null; 352 switch (state) 353 { 354 case Bundle.ACTIVE: 355 s = ACTIVE_STATE; 356 break; 357 case Bundle.UNINSTALLED: 358 s = UNINSTALLED_STATE; 359 break; 360 default: 361 s = INSTALLED_STATE; 362 break; 363 } 364 bw.write(s, 0, s.length()); 365 m_persistentState = state; 366 } 367 catch (IOException ex) 368 { 369 Oscar.error("DefaultBundleArchive: Unable to record state: " + ex); 370 throw ex; 371 } 372 finally 373 { 374 if (bw != null) bw.close(); 375 if (fw != null) fw.close(); 376 } 377 } 378 379 public int getStartLevel() 380 throws Exception 381 { 382 if (m_startLevel >= 0) 383 { 384 return m_startLevel; 385 } 386 else if (System.getSecurityManager() != null) 387 { 388 try 389 { 390 return ((Integer ) AccessController.doPrivileged( 391 new PrivilegedAction( 392 PrivilegedAction.GET_START_LEVEL_ACTION, this))).intValue(); 393 } 394 catch (PrivilegedActionException ex) 395 { 396 throw ((PrivilegedActionException ) ex).getException(); 397 } 398 } 399 else 400 { 401 return getStartLevelUnchecked(); 402 } 403 } 404 405 private int getStartLevelUnchecked() 406 throws Exception 407 { 408 File levelFile = new File (m_dir, BUNDLE_START_LEVEL_FILE); 410 411 if (!levelFile.exists()) 414 { 415 return -1; 416 } 417 418 FileReader fr = null; 420 BufferedReader br= null; 421 try 422 { 423 fr = new FileReader(levelFile); 424 br = new BufferedReader(fr); 425 m_startLevel = Integer.parseInt(br.readLine()); 426 return m_startLevel; 427 } 428 finally 429 { 430 if (br != null) br.close(); 431 if (fr != null) fr.close(); 432 } 433 } 434 435 public void setStartLevel(int level) 436 throws Exception 437 { 438 if (System.getSecurityManager() != null) 439 { 440 try 441 { 442 AccessController.doPrivileged( 443 new PrivilegedAction( 444 PrivilegedAction.SET_START_LEVEL_ACTION, this, level)); 445 } 446 catch (PrivilegedActionException ex) 447 { 448 throw ((PrivilegedActionException ) ex).getException(); 449 } 450 } 451 else 452 { 453 setStartLevelUnchecked(level); 454 } 455 } 456 457 private void setStartLevelUnchecked(int level) 458 throws Exception 459 { 460 File levelFile = new File (m_dir, BUNDLE_START_LEVEL_FILE); 462 463 FileWriter fw = null; 465 BufferedWriter bw = null; 466 try 467 { 468 fw = new FileWriter(levelFile); 469 bw = new BufferedWriter(fw); 470 String s = Integer.toString(level); 471 bw.write(s, 0, s.length()); 472 m_startLevel = level; 473 } 474 catch (IOException ex) 475 { 476 Oscar.error("DefaultBundleArchive: Unable to record start leel: " + ex); 477 throw ex; 478 } 479 finally 480 { 481 if (bw != null) bw.close(); 482 if (fw != null) fw.close(); 483 } 484 } 485 486 public File getDataFile(String fileName) 487 throws Exception 488 { 489 if ((fileName.length() > 0) && (fileName.charAt(0) == File.separatorChar)) 491 throw new IllegalArgumentException ("The data file path must be relative, not absolute."); 492 else if (fileName.indexOf("..") >= 0) 493 throw new IllegalArgumentException ("The data file path cannot contain a reference to the \"..\" directory."); 494 495 File dataDir = new File (m_dir, DATA_DIRECTORY); 497 498 if (System.getSecurityManager() != null) 499 { 500 try 501 { 502 AccessController.doPrivileged( 503 new PrivilegedAction( 504 PrivilegedAction.CREATE_DATA_DIR_ACTION, this, dataDir)); 505 } 506 catch (PrivilegedActionException ex) 507 { 508 throw ((PrivilegedActionException ) ex).getException(); 509 } 510 } 511 else 512 { 513 createDataDirectoryUnchecked(dataDir); 514 } 515 516 return new File (dataDir, fileName); 518 } 519 520 private void createDataDirectoryUnchecked(File dir) 521 throws Exception 522 { 523 if (!dir.exists()) 525 { 526 if (!dir.mkdir()) 527 { 528 throw new IOException("Unable to create bundle data directory."); 529 } 530 } 531 } 532 533 public BundleActivator getActivator(ClassLoader loader) 534 throws Exception 535 { 536 if (System.getSecurityManager() != null) 537 { 538 try 539 { 540 return (BundleActivator) AccessController.doPrivileged( 541 new PrivilegedAction( 542 PrivilegedAction.GET_ACTIVATOR_ACTION, this, loader)); 543 } 544 catch (PrivilegedActionException ex) 545 { 546 throw ((PrivilegedActionException ) ex).getException(); 547 } 548 } 549 else 550 { 551 return getActivatorUnchecked(loader); 552 } 553 } 554 555 private BundleActivator getActivatorUnchecked(ClassLoader loader) 556 throws Exception 557 { 558 File activatorFile = new File (m_dir, BUNDLE_ACTIVATOR_FILE); 560 if (!activatorFile.exists()) 563 return null; 564 565 InputStream is = null; 567 ObjectInputStreamX ois = null; 568 try 569 { 570 is = new FileInputStream(activatorFile); 571 ois = new ObjectInputStreamX(is, loader); 572 Object o = ois.readObject(); 573 return (BundleActivator) o; 574 } 575 catch (Exception ex) 576 { 577 Oscar.error("DefaultBundleArchive: Trying to deserialize."); 578 Oscar.error("DefaultBundleArchive: " + ex); 579 } 580 finally 581 { 582 if (ois != null) ois.close(); 583 if (is != null) is.close(); 584 } 585 586 return null; 587 } 588 589 public void setActivator(Object obj) 590 throws Exception 591 { 592 if (System.getSecurityManager() != null) 593 { 594 try 595 { 596 AccessController.doPrivileged( 597 new PrivilegedAction( 598 PrivilegedAction.SET_ACTIVATOR_ACTION, this, obj)); 599 } 600 catch (PrivilegedActionException ex) 601 { 602 throw ((PrivilegedActionException ) ex).getException(); 603 } 604 } 605 else 606 { 607 setActivatorUnchecked(obj); 608 } 609 } 610 611 private void setActivatorUnchecked(Object obj) 612 throws Exception 613 { 614 if (!(obj instanceof Serializable)) 615 { 616 return; 617 } 618 619 File activatorFile = new File (m_dir, BUNDLE_ACTIVATOR_FILE); 621 622 OutputStream os = null; 624 ObjectOutputStream oos = null; 625 try 626 { 627 os = new FileOutputStream(activatorFile); 628 oos = new ObjectOutputStream(os); 629 oos.writeObject(obj); 630 } 631 catch (IOException ex) 632 { 633 Oscar.error("DefaultBundleArchive: Unable to serialize activator."); 634 Oscar.error("DefaultBundleArchive: " + ex); 635 throw ex; 636 } 637 finally 638 { 639 if (oos != null) oos.close(); 640 if (os != null) os.close(); 641 } 642 } 643 644 public int getRevisionCount() 645 throws Exception 646 { 647 if (System.getSecurityManager() != null) 648 { 649 try 650 { 651 return ((Integer ) AccessController.doPrivileged( 652 new PrivilegedAction( 653 PrivilegedAction.GET_REVISION_COUNT_ACTION, this))).intValue(); 654 } 655 catch (PrivilegedActionException ex) 656 { 657 throw ((PrivilegedActionException ) ex).getException(); 658 } 659 } 660 else 661 { 662 return getRevisionCountUnchecked(); 663 } 664 } 665 666 public int getRevisionCountUnchecked() 667 { 668 if (m_revisionCount <= 0) 672 { 673 m_revisionCount = 0; 674 File [] children = m_dir.listFiles(); 675 for (int i = 0; (children != null) && (i < children.length); i++) 676 { 677 if (children[i].getName().startsWith(REVISION_DIRECTORY)) 678 { 679 m_revisionCount++; 680 } 681 } 682 } 683 return m_revisionCount; 684 } 685 686 public Map getManifestHeader(int revision) 687 throws Exception 688 { 689 if ((revision == (getRevisionCount() - 1)) && (m_currentHeader != null)) 692 { 693 return m_currentHeader; 694 } 695 696 File revisionDir = new File ( 698 m_dir, REVISION_DIRECTORY + getRefreshCount() + "." + revision); 699 700 JarFile jarFile = null; 702 703 try 704 { 705 if (System.getSecurityManager() != null) 707 { 708 jarFile = (JarFile ) AccessController.doPrivileged( 709 new PrivilegedAction( 710 PrivilegedAction.OPEN_BUNDLE_JAR_ACTION, this, revisionDir)); 711 } 712 else 713 { 714 jarFile = openBundleJarUnchecked(revisionDir); 715 } 716 717 if (jarFile == null) 719 { 720 throw new IOException("No JAR file found."); 721 } 722 723 Manifest mf = jarFile.getManifest(); 725 Map map = new CaseInsensitiveMap(mf.getMainAttributes()); 727 if (revision == (getRevisionCount() - 1)) 730 { 731 m_currentHeader = map; 732 } 733 return map; 734 735 } catch (PrivilegedActionException ex) { 736 throw ((PrivilegedActionException ) ex).getException(); 737 } finally { 738 if (jarFile != null) jarFile.close(); 739 } 740 } 741 742 private JarFile openBundleJarUnchecked(File revisionDir) 743 throws Exception 744 { 745 File bundleJar = new File (revisionDir, BUNDLE_JAR_FILE); 747 return new JarFile (bundleJar); 749 } 750 751 public String [] getClassPath(int revision) 752 throws Exception 753 { 754 if (System.getSecurityManager() != null) 755 { 756 try 757 { 758 return (String []) AccessController.doPrivileged( 759 new PrivilegedAction( 760 PrivilegedAction.GET_CLASS_PATH_ACTION, this, revision)); 761 } 762 catch (PrivilegedActionException ex) 763 { 764 throw ((PrivilegedActionException ) ex).getException(); 765 } 766 } 767 else 768 { 769 return getClassPathUnchecked(revision); 770 } 771 } 772 773 private String [] getClassPathUnchecked(int revision) 774 throws Exception 775 { 776 File revisionDir = new File ( 778 m_dir, REVISION_DIRECTORY + getRefreshCount() + "." + revision); 779 780 Map map = getManifestHeader(revision); 782 if (map == null) 783 { 784 map = new HashMap(); 785 } 786 787 String classPath = null; 789 Iterator iter = map.entrySet().iterator(); 790 while ((classPath == null) && iter.hasNext()) 791 { 792 Map.Entry entry = (Map.Entry) iter.next(); 793 if (entry.getKey().toString().toLowerCase().equals( 794 OscarConstants.BUNDLE_CLASSPATH.toLowerCase())) 795 { 796 classPath = entry.getValue().toString(); 797 } 798 } 799 800 String [] classPathStrings = TextUtil.parseCommaDelimitedString(classPath); 802 803 if (classPathStrings == null) 804 { 805 classPathStrings = new String [0]; 806 } 807 808 boolean includeDot = false; 810 for (int i = 0; !includeDot && (i < classPathStrings.length); i++) 811 { 812 if (classPathStrings[i].equals(OscarConstants.CLASS_PATH_DOT)) 813 { 814 includeDot = true; 815 } 816 } 817 818 File embedDir = new File (revisionDir, EMBEDDED_DIRECTORY); 821 String [] paths = null; 822 if (embedDir.exists()) 823 { 824 File [] children = embedDir.listFiles(); 830 int size = (children == null) ? 0 : children.length; 831 size = (includeDot) ? size + 1 : size; 832 paths = new String [size]; 833 for (int i = 0; i < children.length; i++) 834 { 835 paths[(includeDot) ? i + 1 : i] = children[i].getPath(); 838 } 839 } 840 841 if ((paths == null) || (paths.length == 0)) 844 { 845 includeDot = true; 846 paths = new String [1]; 847 } 848 849 if (includeDot) 851 { 852 paths[0] = revisionDir + File.separator + BUNDLE_JAR_FILE; 853 } 854 855 return paths; 856 } 857 858 public String findLibrary(int revision, String libName) 860 throws Exception 861 { 862 return findLibraryUnchecked(revision, libName); 863 } 864 865 private String findLibraryUnchecked(int revision, String libName) 866 throws Exception 867 { 868 File revisionDir = new File ( 870 m_dir.getAbsoluteFile(), 871 REVISION_DIRECTORY + getRefreshCount() + "." + revision); 872 873 File libDir = new File (revisionDir, LIBRARY_DIRECTORY); 875 File libFile = new File (libDir, File.separatorChar + libName); 877 libDir = libFile.getParentFile(); 880 if (!libDir.exists()) 881 { 882 if (!libDir.mkdirs()) 883 { 884 throw new IOException("Unable to create library directory."); 885 } 886 } 887 if (!libFile.exists()) 890 { 891 JarFile jarFile = null; 892 InputStream is = null; 893 894 try 895 { 896 jarFile = openBundleJarUnchecked(revisionDir); 897 ZipEntry ze = jarFile.getEntry(libName); 898 if (ze == null) 899 { 900 throw new IOException("No JAR entry: " + libName); 901 } 902 is = new BufferedInputStream( 903 jarFile.getInputStream(ze), DefaultBundleCache.BUFSIZE); 904 if (is == null) 905 { 906 throw new IOException("No input stream: " + libName); 907 } 908 909 copy(is, libFile); 911 912 } 913 finally 914 { 915 if (jarFile != null) jarFile.close(); 916 if (is != null) is.close(); 917 } 918 } 919 920 return libFile.toString(); 921 } 922 923 937 private long getRefreshCount() 938 throws Exception 939 { 940 if (m_refreshCount >= 0) 943 { 944 return m_refreshCount; 945 } 946 947 File counterFile = new File (m_dir, REFRESH_COUNTER_FILE); 949 950 if (!counterFile.exists()) 953 { 954 return 0; 955 } 956 957 FileReader fr = null; 959 BufferedReader br = null; 960 try 961 { 962 fr = new FileReader(counterFile); 963 br = new BufferedReader(fr); 964 long counter = Long.parseLong(br.readLine()); 965 return counter; 966 } 967 finally 968 { 969 if (br != null) br.close(); 970 if (fr != null) fr.close(); 971 } 972 } 973 974 988 private void setRefreshCount(long counter) 989 throws Exception 990 { 991 File counterFile = new File (m_dir, REFRESH_COUNTER_FILE); 993 994 FileWriter fw = null; 996 BufferedWriter bw = null; 997 try 998 { 999 fw = new FileWriter(counterFile); 1000 bw = new BufferedWriter(fw); 1001 String s = Long.toString(counter); 1002 bw.write(s, 0, s.length()); 1003 m_refreshCount = counter; 1004 } 1005 catch (IOException ex) 1006 { 1007 Oscar.error("DefaultBundleArchive: Unable to write counter: " + ex); 1008 throw ex; 1009 } 1010 finally 1011 { 1012 if (bw != null) bw.close(); 1013 if (fw != null) fw.close(); 1014 } 1015 } 1016 1017 1021 protected static boolean deleteDirectoryTree(File target) 1022 { 1023 if (!target.exists()) 1024 { 1025 return true; 1026 } 1027 1028 if (target.isDirectory()) 1029 { 1030 File [] files = target.listFiles(); 1031 for (int i = 0; i < files.length; i++) 1032 { 1033 deleteDirectoryTree(files[i]); 1034 } 1035 } 1036 1037 return target.delete(); 1038 } 1039 1040 1048 private void copy(InputStream is, File outputFile) 1049 throws IOException 1050 { 1051 OutputStream os = null; 1052 1053 try 1054 { 1055 os = new BufferedOutputStream( 1056 new FileOutputStream(outputFile), DefaultBundleCache.BUFSIZE); 1057 byte[] b = new byte[DefaultBundleCache.BUFSIZE]; 1058 int len = 0; 1059 while ((len = is.read(b)) != -1) 1060 os.write(b, 0, len); 1061 } 1062 finally 1063 { 1064 if (is != null) is.close(); 1065 if (os != null) os.close(); 1066 } 1067 } 1068 1069 1075 private void preprocessBundleJar(int revision, File revisionDir) 1076 throws Exception 1077 { 1078 1083 File embedDir = new File (revisionDir, EMBEDDED_DIRECTORY); 1084 if (!embedDir.exists()) 1085 { 1086 if (!embedDir.mkdir()) 1087 { 1088 throw new IOException("Could not create embedded JAR directory."); 1089 } 1090 } 1091 1092 File libDir = new File (revisionDir, LIBRARY_DIRECTORY); 1093 if (!libDir.exists()) 1094 { 1095 if (!libDir.mkdir()) 1096 { 1097 throw new IOException("Unable to create native library directory."); 1098 } 1099 } 1100 1101 1105 try 1106 { 1107 Map map = getManifestHeader(revision); 1109 if (map == null) 1110 { 1111 map = new HashMap(); 1112 } 1113 1114 String classPath = null; 1116 Iterator iter = map.entrySet().iterator(); 1117 while ((classPath == null) && iter.hasNext()) 1118 { 1119 Map.Entry entry = (Map.Entry) iter.next(); 1120 if (entry.getKey().toString().toLowerCase().equals( 1121 OscarConstants.BUNDLE_CLASSPATH.toLowerCase())) 1122 { 1123 classPath = entry.getValue().toString(); 1124 } 1125 } 1126 1127 String [] classPathStrings = TextUtil.parseCommaDelimitedString(classPath); 1129 1130 if (classPathStrings == null) 1131 { 1132 classPathStrings = new String [0]; 1133 } 1134 1135 for (int i = 0; i < classPathStrings.length; i++) 1136 { 1137 if (!classPathStrings[i].equals(OscarConstants.CLASS_PATH_DOT)) 1138 { 1139 extractEmbeddedJar(revisionDir, classPathStrings[i]); 1140 } 1141 } 1142 1143 } 1144 catch (PrivilegedActionException ex) 1145 { 1146 throw ((PrivilegedActionException ) ex).getException(); 1147 } 1148 } 1149 1150 1159 private void extractEmbeddedJar(File revisionDir, String jarPath) 1160 throws Exception 1161 { 1162 jarPath = (jarPath.charAt(0) == '/') ? jarPath.substring(1) : jarPath; 1164 String jarName = (jarPath.lastIndexOf('/') >= 0) 1166 ? jarPath.substring(jarPath.lastIndexOf('/') + 1) : jarPath; 1167 1168 File embedFile = new File ( 1171 revisionDir, EMBEDDED_DIRECTORY + File.separatorChar + jarName); 1172 if (!embedFile.exists()) 1173 { 1174 JarFile jarFile = null; 1175 InputStream is = null; 1176 1177 try 1178 { 1179 jarFile = openBundleJarUnchecked(revisionDir); 1180 ZipEntry ze = jarFile.getEntry(jarPath); 1181 if (ze == null) 1182 { 1183 throw new IOException("No JAR entry: " + jarPath); 1184 } 1185 is = new BufferedInputStream(jarFile.getInputStream(ze), DefaultBundleCache.BUFSIZE); 1186 if (is == null) 1187 { 1188 throw new IOException("No input stream: " + jarPath); 1189 } 1190 1191 copy(is, embedFile); 1193 1194 } 1195 finally 1196 { 1197 if (jarFile != null) jarFile.close(); 1198 if (is != null) is.close(); 1199 } 1200 } 1201 } 1202 1203 protected void update(InputStream is) throws Exception 1205 { 1206 if (System.getSecurityManager() != null) 1207 { 1208 try 1209 { 1210 AccessController.doPrivileged( 1211 new PrivilegedAction( 1212 PrivilegedAction.UPDATE_ACTION, this, is)); 1213 } 1214 catch (PrivilegedActionException ex) 1215 { 1216 throw ((PrivilegedActionException ) ex).getException(); 1217 } 1218 } 1219 else 1220 { 1221 updateUnchecked(is); 1222 } 1223 } 1224 1225 private void updateUnchecked(InputStream is) throws Exception 1227 { 1228 File revisionDir = null; 1229 1230 try 1231 { 1232 int revision = getRevisionCountUnchecked(); 1234 revisionDir = new File ( 1235 m_dir, REVISION_DIRECTORY 1236 + getRefreshCount() + "." + revision); 1237 if (!revisionDir.mkdir()) 1238 { 1239 throw new IOException("Unable to create revision directory."); 1240 } 1241 1242 File file = new File (revisionDir, BUNDLE_JAR_FILE); 1244 copy(is, file); 1245 1246 preprocessBundleJar(revision, revisionDir); 1247 } 1248 catch (Exception ex) 1249 { 1250 if ((revisionDir != null) && revisionDir.exists()) 1251 { 1252 try 1253 { 1254 deleteDirectoryTree(revisionDir); 1255 } 1256 catch (Exception ex2) 1257 { 1258 Oscar.error("Unable to remove partial revision directory.", ex2); 1260 } 1261 } 1262 throw ex; 1263 } 1264 1265 m_revisionCount++; 1268 m_currentHeader = null; 1271 } 1272 1273 protected void purge() throws Exception 1275 { 1276 if (System.getSecurityManager() != null) 1277 { 1278 try 1279 { 1280 AccessController.doPrivileged( 1281 new PrivilegedAction( 1282 PrivilegedAction.PURGE_ACTION, this)); 1283 } 1284 catch (PrivilegedActionException ex) 1285 { 1286 throw ((PrivilegedActionException ) ex).getException(); 1287 } 1288 } 1289 else 1290 { 1291 purgeUnchecked(); 1292 } 1293 } 1294 1295 private void purgeUnchecked() throws Exception 1297 { 1298 long update = getRefreshCount(); 1300 int count = getRevisionCountUnchecked(); 1302 1303 File revisionDir = null; 1304 for (int i = 0; i < count - 1; i++) 1305 { 1306 revisionDir = new File (m_dir, REVISION_DIRECTORY + update + "." + i); 1307 if (revisionDir.exists()) 1308 { 1309 deleteDirectoryTree(revisionDir); 1310 } 1311 } 1312 setRefreshCount(update + 1); 1314 1315 File currentDir = new File (m_dir, REVISION_DIRECTORY + (update + 1) + ".0"); 1317 revisionDir = new File (m_dir, REVISION_DIRECTORY + update + "." + (count - 1)); 1318 revisionDir.renameTo(currentDir); 1319 1320 m_revisionCount = 1; 1323 m_currentHeader = null; 1326 } 1327 1328 protected void remove() throws Exception 1329 { 1330 if (System.getSecurityManager() != null) 1331 { 1332 try 1333 { 1334 AccessController.doPrivileged( 1335 new PrivilegedAction( 1336 PrivilegedAction.REMOVE_ACTION, this)); 1337 } 1338 catch (PrivilegedActionException ex) 1339 { 1340 throw ((PrivilegedActionException ) ex).getException(); 1341 } 1342 } 1343 else 1344 { 1345 removeUnchecked(); 1346 } 1347 } 1348 1349 private void removeUnchecked() throws Exception 1350 { 1351 deleteDirectoryTree(m_dir); 1352 } 1353 1354 1358 private static class PrivilegedAction implements PrivilegedExceptionAction 1359 { 1360 private static final int INITIALIZE_ACTION = 0; 1361 private static final int UPDATE_ACTION = 1; 1362 private static final int PURGE_ACTION = 2; 1363 private static final int REMOVE_ACTION = 3; 1364 private static final int GET_REVISION_COUNT_ACTION = 4; 1365 private static final int GET_LOCATION_ACTION = 5; 1366 private static final int GET_PERSISTENT_STATE_ACTION = 6; 1367 private static final int SET_PERSISTENT_STATE_ACTION = 7; 1368 private static final int GET_START_LEVEL_ACTION = 8; 1369 private static final int SET_START_LEVEL_ACTION = 9; 1370 private static final int OPEN_BUNDLE_JAR_ACTION = 10; 1371 private static final int CREATE_DATA_DIR_ACTION = 11; 1372 private static final int GET_CLASS_PATH_ACTION = 12; 1373 private static final int GET_ACTIVATOR_ACTION = 13; 1374 private static final int SET_ACTIVATOR_ACTION = 14; 1375 1376 private int m_action = 0; 1377 private DefaultBundleArchive m_archive = null; 1378 private InputStream m_isArg = null; 1379 private String m_strArg = null; 1380 private int m_intArg = 0; 1381 private File m_fileArg = null; 1382 private ClassLoader m_loaderArg = null; 1383 private Object m_objArg = null; 1384 1385 public PrivilegedAction(int action, DefaultBundleArchive archive) 1386 { 1387 m_action = action; 1388 m_archive = archive; 1389 } 1390 1391 public PrivilegedAction(int action, DefaultBundleArchive archive, InputStream isArg) 1392 { 1393 m_action = action; 1394 m_archive = archive; 1395 m_isArg = isArg; 1396 } 1397 1398 public PrivilegedAction(int action, DefaultBundleArchive archive, int intArg) 1399 { 1400 m_action = action; 1401 m_archive = archive; 1402 m_intArg = intArg; 1403 } 1404 1405 public PrivilegedAction(int action, DefaultBundleArchive archive, File fileArg) 1406 { 1407 m_action = action; 1408 m_archive = archive; 1409 m_fileArg = fileArg; 1410 } 1411 1412 public PrivilegedAction(int action, DefaultBundleArchive archive, ClassLoader loaderArg) 1413 { 1414 m_action = action; 1415 m_archive = archive; 1416 m_loaderArg = loaderArg; 1417 } 1418 1419 public PrivilegedAction(int action, DefaultBundleArchive archive, Object objArg) 1420 { 1421 m_action = action; 1422 m_archive = archive; 1423 m_objArg = objArg; 1424 } 1425 1426 public Object run() throws Exception 1427 { 1428 switch (m_action) 1429 { 1430 case INITIALIZE_ACTION: 1431 m_archive.initializeUnchecked(m_isArg); 1432 return null; 1433 case UPDATE_ACTION: 1434 m_archive.updateUnchecked(m_isArg); 1435 return null; 1436 case PURGE_ACTION: 1437 m_archive.purgeUnchecked(); 1438 return null; 1439 case REMOVE_ACTION: 1440 m_archive.removeUnchecked(); 1441 return null; 1442 case GET_REVISION_COUNT_ACTION: 1443 return new Integer (m_archive.getRevisionCountUnchecked()); 1444 case GET_LOCATION_ACTION: 1445 return m_archive.getLocationUnchecked(); 1446 case GET_PERSISTENT_STATE_ACTION: 1447 return new Integer (m_archive.getPersistentStateUnchecked()); 1448 case SET_PERSISTENT_STATE_ACTION: 1449 m_archive.setPersistentStateUnchecked(m_intArg); 1450 return null; 1451 case GET_START_LEVEL_ACTION: 1452 return new Integer (m_archive.getStartLevelUnchecked()); 1453 case SET_START_LEVEL_ACTION: 1454 m_archive.setStartLevelUnchecked(m_intArg); 1455 return null; 1456 case OPEN_BUNDLE_JAR_ACTION: 1457 return m_archive.openBundleJarUnchecked(m_fileArg); 1458 case CREATE_DATA_DIR_ACTION: 1459 m_archive.createDataDirectoryUnchecked(m_fileArg); 1460 return null; 1461 case GET_CLASS_PATH_ACTION: 1462 return m_archive.getClassPathUnchecked(m_intArg); 1463 case GET_ACTIVATOR_ACTION: 1464 return m_archive.getActivatorUnchecked(m_loaderArg); 1465 case SET_ACTIVATOR_ACTION: 1466 m_archive.setActivatorUnchecked(m_objArg); 1467 return null; 1468 } 1469 1470 throw new IllegalArgumentException ("Invalid action specified."); 1471 } 1472 } 1473} | Popular Tags |