1 11 12 package org.eclipse.osgi.framework.adaptor.core; 13 14 import java.io.*; 15 import java.lang.reflect.InvocationTargetException ; 16 import java.lang.reflect.Method ; 17 import java.net.URL ; 18 import java.net.URLConnection ; 19 import java.util.*; 20 import org.eclipse.osgi.framework.adaptor.*; 21 import org.eclipse.osgi.framework.debug.Debug; 22 import org.eclipse.osgi.framework.internal.core.*; 23 import org.eclipse.osgi.framework.internal.core.Constants; 24 import org.eclipse.osgi.framework.log.FrameworkLog; 25 import org.eclipse.osgi.framework.util.Headers; 26 import org.eclipse.osgi.service.resolver.*; 27 import org.eclipse.osgi.util.ManifestElement; 28 import org.eclipse.osgi.util.NLS; 29 import org.osgi.framework.*; 30 31 39 public abstract class AbstractFrameworkAdaptor implements FrameworkAdaptor { 40 43 public static final String PROP_PARENT_CLASSLOADER = "osgi.parentClassloader"; 47 public static final String PROP_FRAMEWORK_EXTENSIONS = "osgi.framework.extensions"; 51 public static final String PROP_SIGNINGSUPPORT = "osgi.bundlesigning.support"; 55 public static final String PARENT_CLASSLOADER_APP = "app"; 59 public static final String PARENT_CLASSLOADER_EXT = "ext"; 63 public static final String PARENT_CLASSLOADER_BOOT = "boot"; 67 public static final String PARENT_CLASSLOADER_FWK = "fwk"; 71 public static final String BUNDLEFILE_NAME = "bundlefile"; 73 76 public static final byte EXTENSION_INITIALIZE = 0x01; 77 80 public static final byte EXTENSION_INSTALLED = 0x02; 81 84 public static final byte EXTENSION_UNINSTALLED = 0x04; 85 88 public static final byte EXTENSION_UPDATED = 0x08; 89 90 91 protected final String ADAPTOR_MANIFEST = "ADAPTOR.MF"; 93 96 protected final String DEFAULT_SIGNEDBUNDLE_SUPPORT = "org.eclipse.osgi.framework.pkcs7verify.SignedBundleSupportImpl"; 98 101 protected EventPublisher eventPublisher; 102 103 106 protected ServiceRegistry serviceRegistry; 107 108 111 protected Properties properties; 112 113 116 protected BundleContext context; 117 118 121 protected int initialBundleStartLevel = 1; 122 123 124 protected Headers manifest = null; 125 126 130 protected boolean stopping = false; 131 132 137 protected static ClassLoader bundleClassLoaderParent; 138 141 protected long nextId = 1; 142 145 protected StateManager stateManager; 146 149 protected File bundleStoreRootDir; 150 151 154 protected AdaptorElementFactory elementFactory; 155 156 static { 157 String type = System.getProperty(PROP_PARENT_CLASSLOADER, PARENT_CLASSLOADER_BOOT); 159 if (PARENT_CLASSLOADER_FWK.equalsIgnoreCase(type)) 160 bundleClassLoaderParent = FrameworkAdaptor.class.getClassLoader(); 161 else if (PARENT_CLASSLOADER_APP.equalsIgnoreCase(type)) 162 bundleClassLoaderParent = ClassLoader.getSystemClassLoader(); 163 else if (PARENT_CLASSLOADER_EXT.equalsIgnoreCase(type)) { 164 ClassLoader appCL = ClassLoader.getSystemClassLoader(); 165 if (appCL != null) 166 bundleClassLoaderParent = appCL.getParent(); 167 } 168 169 if (bundleClassLoaderParent == null) 171 bundleClassLoaderParent = new ParentClassLoader(); 172 } 173 174 177 protected Method addURLMethod; 178 179 182 protected String [] configuredExtensions; 183 184 187 protected boolean supportSignedBundles = true; 188 191 protected SignedBundleSupport signedBundleSupport = null; 192 193 210 public AbstractFrameworkAdaptor(String [] args) { 211 ClassLoader fwloader = AbstractFrameworkAdaptor.class.getClassLoader(); 212 if (fwloader != null) 213 addURLMethod = findaddURLMethod(fwloader.getClass()); 214 if (args != null) { 215 for (int i = 0; i < args.length; i++) { 216 String arg = args[i]; 217 if (arg.equalsIgnoreCase("reset")) { reset = true; 219 } else if (arg.indexOf("=") != -1) { StringTokenizer tok = new StringTokenizer(args[i], "="); if (tok.countTokens() == 2) { 222 String key = tok.nextToken(); 223 if (key.equalsIgnoreCase("bundledir")) { bundleStore = tok.nextToken(); 226 } 227 } 228 } 229 } 230 } 231 } 232 233 236 public void initialize(EventPublisher eventPublisher) { 237 this.eventPublisher = eventPublisher; 238 serviceRegistry = new ServiceRegistryImpl(); 239 ((ServiceRegistryImpl) serviceRegistry).initialize(); 240 loadProperties(); 241 readAdaptorManifest(); 242 initBundleStoreRootDir(); 243 frameworkLog = createFrameworkLog(); 245 } 246 247 250 public Properties getProperties() { 251 return properties; 252 } 253 254 260 public abstract AdaptorElementFactory getElementFactory(); 261 262 267 protected abstract void persistNextBundleID(long value) throws IOException; 268 269 272 public FrameworkLog getFrameworkLog() { 273 if (frameworkLog == null) 274 frameworkLog = createFrameworkLog(); 275 return frameworkLog; 276 } 277 278 281 public State getState() { 282 return stateManager.getSystemState(); 283 } 284 285 288 public PlatformAdmin getPlatformAdmin() { 289 return stateManager; 290 } 291 292 295 public URLConnection mapLocationToURLConnection(String location) throws BundleException { 296 try { 297 return (new URL (location).openConnection()); 298 } catch (IOException e) { 299 throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_URL_CREATE_EXCEPTION, location), e); 300 } 301 } 302 303 309 public long getTotalFreeSpace() throws IOException { 310 return -1; 311 } 312 313 316 public org.eclipse.osgi.framework.adaptor.ServiceRegistry getServiceRegistry() { 317 return serviceRegistry; 318 } 319 320 323 public void frameworkStart(BundleContext context) throws BundleException { 324 this.stopping = false; 325 this.context = context; 326 BundleResourceHandler.setContext(context); 327 if (frameworkLog == null) 328 frameworkLog = createFrameworkLog(); 329 if (stateManager == null) 330 stateManager = createStateManager(); 331 State state = stateManager.getSystemState(); 332 checkSystemState(state); 333 BundleDescription systemBundle = state.getBundle(0); 334 if (systemBundle == null || !systemBundle.isResolved()) 335 throw new IllegalStateException (); 337 } 338 339 342 public void frameworkStop(BundleContext context) throws BundleException { 343 shutdownStateManager(); 344 this.context = null; 345 BundleResourceHandler.setContext(null); 346 frameworkLog.close(); 347 frameworkLog = null; 348 } 349 350 353 public void frameworkStopping(BundleContext context) { 354 this.stopping = true; 355 } 356 357 360 public String getExportPackages() { 361 if (manifest == null) 362 return null; 363 return (String ) manifest.get(Constants.EXPORT_PACKAGE); 364 } 365 366 369 public String getExportServices() { 370 if (manifest == null) 371 return null; 372 return (String ) manifest.get(Constants.EXPORT_SERVICE); 373 } 374 375 378 public String getProvidePackages() { 379 if (manifest == null) 380 return null; 381 return (String ) manifest.get(Constants.PROVIDE_PACKAGE); 382 } 383 384 388 public EventPublisher getEventPublisher() { 389 return eventPublisher; 390 } 391 392 396 public boolean isStopping() { 397 return stopping; 398 } 399 400 403 public int getInitialBundleStartLevel() { 404 return initialBundleStartLevel; 405 } 406 407 410 public void setInitialBundleStartLevel(int value) { 411 initialBundleStartLevel = value; 412 } 413 414 417 public BundleWatcher getBundleWatcher() { 418 return null; 419 } 420 421 424 protected FrameworkLog frameworkLog; 425 426 public static final String BUNDLE_STORE = "osgi.bundlestore"; 428 440 protected void loadProperties() { 441 properties = new Properties(); 442 443 String resource = System.getProperty(Constants.OSGI_PROPERTIES, Constants.DEFAULT_OSGI_PROPERTIES); 444 445 try { 446 InputStream in = null; 447 File file = new File(resource); 448 if (file.exists()) { 449 in = new FileInputStream(file); 450 } 451 452 if (in == null) { 453 in = getClass().getResourceAsStream(resource); 454 } 455 456 if (in != null) { 457 try { 458 properties.load(new BufferedInputStream(in)); 459 } finally { 460 try { 461 in.close(); 462 } catch (IOException ee) { 463 } 464 } 465 } else { 466 if (Debug.DEBUG && Debug.DEBUG_GENERAL) 467 Debug.println("Skipping osgi.properties: " + resource); } 469 } catch (IOException e) { 470 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 471 Debug.println("Unable to load osgi.properties: " + e.getMessage()); } 473 } 474 475 if (addURLMethod != null) 477 properties.put(Constants.SUPPORTS_FRAMEWORK_EXTENSION, "true"); } 479 480 486 protected synchronized long getNextBundleId() throws IOException { 487 while (nextId < Long.MAX_VALUE) { 488 long id = nextId; 489 nextId++; 490 491 File bundleDir = new File(getBundleStoreRootDir(), String.valueOf(id)); 492 if (bundleDir.exists()) { 493 continue; 494 } 495 persistNextBundleID(id); 496 return (id); 497 } 498 499 throw new IOException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION); 500 } 501 502 506 protected void initDataRootDir() { 507 dataRootDir = getBundleStoreRootDir(); 508 } 509 510 515 protected void readAdaptorManifest() { 516 InputStream in = null; 517 Class adaptorClazz = getClass(); 519 while (in == null && AbstractFrameworkAdaptor.class.isAssignableFrom(adaptorClazz)) { 520 in = adaptorClazz.getResourceAsStream(ADAPTOR_MANIFEST); 521 adaptorClazz = adaptorClazz.getSuperclass(); 522 } 523 524 if (in == null) { 525 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 526 Debug.println("Unable to find adaptor bundle manifest " + ADAPTOR_MANIFEST); } 528 manifest = new Headers(new Properties()); 529 return; 530 } 531 try { 532 manifest = Headers.parseManifest(in); 533 } catch (BundleException e) { 534 Debug.println("Unable to read adaptor bundle manifest " + ADAPTOR_MANIFEST); } 536 } 537 538 542 abstract protected FrameworkLog createFrameworkLog(); 543 544 547 public BundleData createSystemBundleData() throws BundleException { 548 return new SystemBundleData(this); 549 } 550 551 557 public static void copyDir(File inDir, File outDir) throws IOException { 558 String [] files = inDir.list(); 559 if (files != null && files.length > 0) { 560 outDir.mkdir(); 561 for (int i = 0; i < files.length; i++) { 562 File inFile = new File(inDir, files[i]); 563 File outFile = new File(outDir, files[i]); 564 if (inFile.isDirectory()) { 565 copyDir(inFile, outFile); 566 } else { 567 InputStream in = new FileInputStream(inFile); 568 readFile(in, outFile); 569 } 570 } 571 } 572 } 573 574 581 public static void readFile(InputStream in, File file) throws IOException { 582 FileOutputStream fos = null; 583 try { 584 fos = new FileOutputStream(file); 585 586 byte buffer[] = new byte[1024]; 587 int count; 588 while ((count = in.read(buffer, 0, buffer.length)) > 0) { 589 fos.write(buffer, 0, count); 590 } 591 592 fos.close(); 593 fos = null; 594 595 in.close(); 596 in = null; 597 } catch (IOException e) { 598 if (fos != null) { 600 try { 601 fos.close(); 602 } catch (IOException ee) { 603 } 604 } 605 606 if (in != null) { 607 try { 608 in.close(); 609 } catch (IOException ee) { 610 } 611 } 612 613 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 614 Debug.println("Unable to read file"); Debug.printStackTrace(e); 616 } 617 618 throw e; 619 } 620 } 621 622 private static Method findaddURLMethod(Class clazz) { 623 if (clazz == null) 624 return null; try { 626 Method result = clazz.getDeclaredMethod("addURL", new Class [] {URL .class}); result.setAccessible(true); 628 return result; 629 } catch (NoSuchMethodException e) { 630 } catch (SecurityException e) { 632 } 634 return findaddURLMethod(clazz.getSuperclass()); 635 } 636 637 640 public ClassLoader getBundleClassLoaderParent() { 641 return bundleClassLoaderParent; 642 } 643 644 650 protected void processExtension(BundleData bundleData, byte type) throws BundleException { 651 if ((bundleData.getType() & BundleData.TYPE_FRAMEWORK_EXTENSION) != 0) { 652 validateExtension(bundleData); 653 processFrameworkExtension(bundleData, type); 654 } else if ((bundleData.getType() & BundleData.TYPE_BOOTCLASSPATH_EXTENSION) != 0) { 655 validateExtension(bundleData); 656 processBootExtension(bundleData, type); 657 } 658 } 659 660 665 protected void validateExtension(BundleData bundleData) throws BundleException { 666 Dictionary extensionManifest = bundleData.getManifest(); 667 if (extensionManifest.get(Constants.IMPORT_PACKAGE) != null) 668 throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_EXTENSION_IMPORT_ERROR, bundleData.getLocation())); 669 if (extensionManifest.get(Constants.REQUIRE_BUNDLE) != null) 670 throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_EXTENSION_REQUIRE_ERROR, bundleData.getLocation())); 671 if (extensionManifest.get(Constants.BUNDLE_NATIVECODE) != null) 672 throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_EXTENSION_NATIVECODE_ERROR, bundleData.getLocation())); 673 } 674 675 681 protected void processFrameworkExtension(BundleData bundleData, byte type) throws BundleException { 682 if (addURLMethod == null) 683 throw new BundleException("Framework extensions are not supported.", new UnsupportedOperationException ()); if ((type & (EXTENSION_UNINSTALLED | EXTENSION_UPDATED)) != 0) 685 return; 687 688 String [] extensions = getConfiguredExtensions(); 690 for (int i = 0; i < extensions.length; i++) 691 if (extensions[i].equals(bundleData.getSymbolicName())) 692 return; 693 File[] files = getExtensionFiles(bundleData); 694 if (files == null) 695 return; 696 for (int i = 0; i < files.length; i++) { 697 if (files[i] == null) 698 continue; 699 Throwable exceptionLog = null; 700 try { 701 addURLMethod.invoke(getClass().getClassLoader(), new Object [] {files[i].toURL()}); 702 } catch (InvocationTargetException e) { 703 exceptionLog = e.getTargetException(); 704 } catch (Throwable t) { 705 exceptionLog = t; 706 } finally { 707 if (exceptionLog != null) 708 eventPublisher.publishFrameworkEvent(FrameworkEvent.ERROR, ((AbstractBundleData) bundleData).getBundle(), exceptionLog); 709 } 710 } 711 } 712 713 717 protected String [] getConfiguredExtensions() { 718 if (configuredExtensions != null) 719 return configuredExtensions; 720 String prop = System.getProperty(PROP_FRAMEWORK_EXTENSIONS); 721 if (prop == null || prop.trim().length() == 0) 722 configuredExtensions = new String [0]; 723 else 724 configuredExtensions = ManifestElement.getArrayFromList(prop); 725 return configuredExtensions; 726 } 727 728 734 protected void processBootExtension(BundleData bundleData, byte type) throws BundleException { 735 throw new BundleException("Boot classpath extensions are not supported.", new UnsupportedOperationException ()); } 737 738 743 protected File[] getExtensionFiles(BundleData bundleData) { 744 File[] files = null; 745 try { 746 String [] paths = bundleData.getClassPath(); 747 if (System.getProperty("osgi.dev") != null) { String [] origPaths = paths; 750 paths = new String [origPaths.length + 1]; 751 System.arraycopy(origPaths, 0, paths, 0, origPaths.length); 752 paths[paths.length - 1] = "bin"; } 754 files = ((AbstractBundleData) bundleData).getClasspathFiles(paths); 755 } catch (BundleException e) { 756 eventPublisher.publishFrameworkEvent(FrameworkEvent.ERROR, ((AbstractBundleData) bundleData).getBundle(), e); 757 } 758 return files; 759 } 760 761 764 public void handleRuntimeError(Throwable error) { 765 } 767 768 772 public File getDataRootDir() { 773 if (dataRootDir == null) 774 initDataRootDir(); 775 return dataRootDir; 776 } 777 778 789 public BundleFile createBundleFile(File basefile, BundleData bundledata) throws IOException { 790 if (basefile.isDirectory()) 791 return new BundleFile.DirBundleFile(basefile); 792 return new BundleFile.ZipBundleFile(basefile, bundledata); 793 } 794 795 802 public BundleFile createBaseBundleFile(File basefile, BundleData bundledata) throws IOException { 803 BundleFile base = createBundleFile(basefile, bundledata); 804 if (System.getSecurityManager() == null || !supportSignedBundles) 805 return base; 806 SignedBundleSupport support = getSignedBundleSupport(); 807 if (support == null) 808 return base; 809 SignedBundle signedBundle = support.createSignedBundle(); 810 signedBundle.setBundleFile(base); 811 return signedBundle; 812 } 813 814 817 public boolean matchDNChain(String pattern, String [] dnChain) { 818 SignedBundleSupport support = getSignedBundleSupport(); 819 if (support != null) 820 return support.matchDNChain(pattern, dnChain); 821 return false; 822 } 823 824 830 protected SignedBundleSupport getSignedBundleSupport() { 831 if (System.getSecurityManager() == null || !supportSignedBundles) 832 return null; 833 try { 834 if (signedBundleSupport == null) { 835 String clazzName = System.getProperty(PROP_SIGNINGSUPPORT, DEFAULT_SIGNEDBUNDLE_SUPPORT); 836 Class clazz = Class.forName(clazzName); 837 signedBundleSupport = (SignedBundleSupport) clazz.newInstance(); 838 } 839 return signedBundleSupport; 840 } catch (ClassNotFoundException e) { 841 supportSignedBundles = false; 842 } catch (IllegalAccessException e) { 843 supportSignedBundles = false; 844 } catch (InstantiationException e) { 845 supportSignedBundles = false; 846 } 847 return null; 848 } 849 850 853 public BundleOperation installBundle(final String location, final URLConnection source) { 854 return (new BundleOperation() { 855 private AbstractBundleData data; 856 857 863 public org.eclipse.osgi.framework.adaptor.BundleData begin() throws BundleException { 864 long id; 865 866 try { 867 871 InputStream in = source.getInputStream(); 872 URL sourceURL = source.getURL(); 873 String protocol = sourceURL == null ? null : sourceURL.getProtocol(); 874 try { 875 try { 876 id = getNextBundleId(); 877 } catch (IOException e) { 878 throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e); 879 } 880 data = getElementFactory().createBundleData(AbstractFrameworkAdaptor.this, id); 881 data.setLastModified(System.currentTimeMillis()); 882 data.setLocation(location); 883 data.setStartLevel(getInitialBundleStartLevel()); 884 885 if (in instanceof ReferenceInputStream) { 886 URL reference = ((ReferenceInputStream) in).getReference(); 887 888 if (!"file".equals(reference.getProtocol())) { throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_URL_CREATE_EXCEPTION, reference)); 890 } 891 892 data.setReference(true); 893 data.setFileName(reference.getPath()); 894 data.initializeNewBundle(); 895 } else { 896 File genDir = data.createGenerationDir(); 897 if (!genDir.exists()) { 898 throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, genDir.getPath())); 899 } 900 901 String fileName = BUNDLEFILE_NAME; 902 File outFile = new File(genDir, fileName); 903 if ("file".equals(protocol)) { File inFile = new File(source.getURL().getPath()); 905 if (inFile.isDirectory()) { 906 copyDir(inFile, outFile); 907 } else { 908 readFile(in, outFile); 909 } 910 } else { 911 readFile(in, outFile); 912 } 913 data.setReference(false); 914 data.setFileName(fileName); 915 data.initializeNewBundle(); 916 } 917 } finally { 918 try { 919 in.close(); 920 } catch (IOException e) { 921 } 922 } 923 } catch (IOException ioe) { 924 throw new BundleException(AdaptorMsg.BUNDLE_READ_EXCEPTION, ioe); 925 } 926 927 return (data); 928 } 929 930 public void undo() { 931 if (data != null) { 932 try { 933 data.close(); 934 } catch (IOException e) { 935 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 936 Debug.println("Unable to close " + data + ": " + e.getMessage()); } 938 } 939 } 940 941 if (data != null) { 942 File bundleDir = data.getBundleStoreDir(); 943 944 if (!rm(bundleDir)) { 945 948 File delete = new File(bundleDir, ".delete"); 950 if (!delete.exists()) { 951 try { 952 953 FileOutputStream out = new FileOutputStream(delete); 954 out.close(); 955 } catch (IOException e) { 956 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 957 Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); } 959 } 960 } 961 } 962 } 963 } 964 965 public void commit(boolean postpone) throws BundleException { 966 processExtension(data, EXTENSION_INSTALLED); 967 try { 968 data.save(); 969 } catch (IOException e) { 970 throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e); 971 } 972 updateState(data, BundleEvent.INSTALLED); 973 } 974 975 }); 976 } 977 978 984 protected boolean rm(File file) { 985 if (file.exists()) { 986 if (file.isDirectory()) { 987 String list[] = file.list(); 988 if (list != null) { 989 int len = list.length; 990 for (int i = 0; i < len; i++) { 991 rm(new File(file, list[i])); 993 } 994 } 995 } 996 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 997 if (file.isDirectory()) { 998 Debug.println("rmdir " + file.getPath()); } else { 1000 Debug.println("rm " + file.getPath()); } 1002 } 1003 1004 boolean success = file.delete(); 1005 1006 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 1007 if (!success) { 1008 Debug.println(" rm failed!!"); } 1010 } 1011 1012 return (success); 1013 } 1014 return (true); 1015 } 1016 1017 1021 protected void shutdownStateManager() { 1022 try { 1023 if (canWrite() && (getBundleStoreRootDir().exists() || getBundleStoreRootDir().mkdirs())) 1024 stateManager.shutdown(new File(getBundleStoreRootDir(), ".state"), new File(getBundleStoreRootDir(), ".lazy")); } catch (IOException e) { 1026 frameworkLog.log(new FrameworkEvent(FrameworkEvent.ERROR, context.getBundle(), e)); 1027 } finally { 1028 stateManager = null; 1029 } 1030 } 1031 1032 1036 public File getBundleStoreRootDir() { 1037 return bundleStoreRootDir; 1038 } 1039 1040 1043 protected String bundleStore = null; 1044 1047 protected PermissionStorage permissionStore; 1048 1051 protected boolean reset = false; 1052 1055 protected File dataRootDir; 1056 1059 public static final String DATA_DIR_NAME = "data"; 1065 protected boolean invalidState = false; 1066 1067 1070 public BundleOperation updateBundle(final org.eclipse.osgi.framework.adaptor.BundleData bundledata, final URLConnection source) { 1071 return (new BundleOperation() { 1072 private AbstractBundleData data; 1073 private AbstractBundleData newData; 1074 1075 1080 public org.eclipse.osgi.framework.adaptor.BundleData begin() throws BundleException { 1081 this.data = (AbstractBundleData) bundledata; 1082 try { 1083 InputStream in = source.getInputStream(); 1084 URL sourceURL = source.getURL(); 1085 String protocol = sourceURL == null ? null : sourceURL.getProtocol(); 1086 try { 1087 if (in instanceof ReferenceInputStream) { 1088 ReferenceInputStream refIn = (ReferenceInputStream) in; 1089 URL reference = (refIn).getReference(); 1090 if (!"file".equals(reference.getProtocol())) { throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_URL_CREATE_EXCEPTION, reference)); 1092 } 1093 String path = reference.getPath(); 1096 if (path.equals(data.getFileName())) { 1097 throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_SAME_REF_UPDATE, reference)); 1098 } 1099 try { 1100 newData = data.nextGeneration(reference.getPath()); 1101 } catch (IOException e) { 1102 throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e); 1103 } 1104 File bundleGenerationDir = newData.createGenerationDir(); 1105 if (!bundleGenerationDir.exists()) { 1106 throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, bundleGenerationDir.getPath())); 1107 } 1108 newData.createBaseBundleFile(); 1109 } else { 1110 try { 1111 newData = data.nextGeneration(null); 1112 } catch (IOException e) { 1113 throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e); 1114 } 1115 File bundleGenerationDir = newData.createGenerationDir(); 1116 if (!bundleGenerationDir.exists()) { 1117 throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, bundleGenerationDir.getPath())); 1118 } 1119 File outFile = newData.getBaseFile(); 1120 if ("file".equals(protocol)) { File inFile = new File(source.getURL().getPath()); 1122 if (inFile.isDirectory()) { 1123 copyDir(inFile, outFile); 1124 } else { 1125 readFile(in, outFile); 1126 } 1127 } else { 1128 readFile(in, outFile); 1129 } 1130 newData.createBaseBundleFile(); 1131 } 1132 } finally { 1133 try { 1134 in.close(); 1135 } catch (IOException ee) { 1136 } 1137 } 1138 newData.loadFromManifest(); 1139 } catch (IOException e) { 1140 throw new BundleException(AdaptorMsg.BUNDLE_READ_EXCEPTION, e); 1141 } 1142 1143 return (newData); 1144 } 1145 1146 1153 1154 public void commit(boolean postpone) throws BundleException { 1155 processExtension(data, EXTENSION_UNINSTALLED); processExtension(newData, EXTENSION_UPDATED); try { 1158 newData.setLastModified(System.currentTimeMillis()); 1159 newData.save(); 1160 } catch (IOException e) { 1161 throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e); 1162 } 1163 updateState(newData, BundleEvent.UPDATED); 1164 File originalGenerationDir = data.createGenerationDir(); 1165 1166 if (postpone || !rm(originalGenerationDir)) { 1167 1170 File delete = new File(originalGenerationDir, ".delete"); 1172 if (!delete.exists()) { 1173 try { 1174 1175 FileOutputStream out = new FileOutputStream(delete); 1176 out.close(); 1177 } catch (IOException e) { 1178 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 1179 Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); } 1181 1182 eventPublisher.publishFrameworkEvent(FrameworkEvent.ERROR, data.getBundle(), e); 1183 } 1184 } 1185 } 1186 } 1187 1188 1193 public void undo() throws BundleException { 1194 1198 1199 if (newData != null) { 1200 File nextGenerationDir = newData.createGenerationDir(); 1201 1202 if (!rm(nextGenerationDir)) { 1203 1206 File delete = new File(nextGenerationDir, ".delete"); 1208 if (!delete.exists()) { 1209 try { 1210 1211 FileOutputStream out = new FileOutputStream(delete); 1212 out.close(); 1213 } catch (IOException e) { 1214 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 1215 Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); } 1217 } 1218 } 1219 } 1220 } 1221 } 1222 }); 1223 } 1224 1225 1230 protected void checkSystemState(State state) { 1231 BundleDescription[] bundles = state.getBundles(); 1232 if (bundles == null) 1233 return; 1234 boolean removedBundle = false; 1235 for (int i = 0; i < bundles.length; i++) { 1236 if (context.getBundle(bundles[i].getBundleId()) == null) { 1237 state.removeBundle(bundles[i]); 1238 removedBundle = true; 1239 } 1240 } 1241 if (removedBundle) 1242 state.resolve(false); } 1244 1245 1249 protected StateManager createStateManager() { 1250 stateManager = new StateManager(new File(getBundleStoreRootDir(), ".state"), new File(getBundleStoreRootDir(), ".lazy"), context); State systemState = null; 1252 if (!invalidState) { 1253 systemState = stateManager.readSystemState(); 1254 if (systemState != null) 1255 return stateManager; 1256 } 1257 systemState = stateManager.createSystemState(); 1258 Bundle[] installedBundles = context.getBundles(); 1259 if (installedBundles == null) 1260 return stateManager; 1261 StateObjectFactory factory = stateManager.getFactory(); 1262 for (int i = 0; i < installedBundles.length; i++) { 1263 Bundle toAdd = installedBundles[i]; 1264 try { 1265 Dictionary manifest = toAdd.getHeaders(""); BundleDescription newDescription = factory.createBundleDescription(systemState, manifest, toAdd.getLocation(), toAdd.getBundleId()); 1267 systemState.addBundle(newDescription); 1268 } catch (BundleException be) { 1269 } 1271 } 1272 systemState.resolve(); 1274 invalidState = false; 1275 return stateManager; 1276 } 1277 1278 1281 public BundleOperation uninstallBundle(final org.eclipse.osgi.framework.adaptor.BundleData bundledata) { 1282 return (new BundleOperation() { 1283 private AbstractBundleData data; 1284 1285 1291 public org.eclipse.osgi.framework.adaptor.BundleData begin() throws BundleException { 1292 this.data = (AbstractBundleData) bundledata; 1293 return (bundledata); 1294 } 1295 1296 1303 public void commit(boolean postpone) throws BundleException { 1304 File bundleDir = data.getBundleStoreDir(); 1305 1306 if (postpone || !rm(bundleDir)) { 1307 1310 1311 File delete = new File(bundleDir, ".delete"); 1313 if (!delete.exists()) { 1314 try { 1315 1316 FileOutputStream out = new FileOutputStream(delete); 1317 out.close(); 1318 } catch (IOException e) { 1319 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 1320 Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); } 1322 } 1323 } 1324 } 1325 1326 processExtension(data, EXTENSION_UNINSTALLED); 1327 data.setLastModified(System.currentTimeMillis()); 1328 updateState(data, BundleEvent.UNINSTALLED); 1329 } 1330 1331 1336 public void undo() throws BundleException { 1337 } 1338 }); 1339 } 1340 1341 1351 protected void initBundleStoreRootDir() { 1352 1353 if (bundleStore == null) { 1354 1355 bundleStore = System.getProperty(BUNDLE_STORE); 1356 1357 if (bundleStore == null) { 1358 1359 bundleStore = properties.getProperty(BUNDLE_STORE, "bundles"); } 1361 } 1362 1363 bundleStoreRootDir = new File(bundleStore); 1364 1365 properties.put(BUNDLE_STORE, bundleStoreRootDir.getAbsolutePath()); 1366 1367 } 1368 1369 1376 protected ServiceRegistration register(String name, Object service, Bundle bundle) { 1377 Hashtable properties = new Hashtable(7); 1378 1379 Dictionary headers = bundle.getHeaders(); 1380 1381 properties.put(Constants.SERVICE_VENDOR, headers.get(Constants.BUNDLE_VENDOR)); 1382 1383 properties.put(Constants.SERVICE_RANKING, new Integer (Integer.MAX_VALUE)); 1384 1385 properties.put(Constants.SERVICE_PID, bundle.getBundleId() + "." + service.getClass().getName()); 1387 return context.registerService(name, service, properties); 1388 } 1389 1390 1406 public void initializeStorage() throws IOException { 1407 File bundleStore; 1408 if (reset && (bundleStore = getBundleStoreRootDir()).exists()) { 1411 if (!canWrite() || !rm(bundleStore)) { 1412 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 1413 Debug.println("Could not remove directory: " + bundleStore.getPath()); } 1415 1416 throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_REMOVE_EXCEPTION, bundleStore)); 1417 } 1418 } 1419 1420 initializeMetadata(); 1421 } 1422 1423 1427 abstract protected void initializeMetadata() throws IOException; 1428 1429 1432 public org.eclipse.osgi.framework.adaptor.PermissionStorage getPermissionStorage() throws IOException { 1433 if (permissionStore == null) { 1434 synchronized (this) { 1435 if (permissionStore == null) { 1436 permissionStore = new DefaultPermissionStorage(this); 1437 } 1438 } 1439 } 1440 1441 return permissionStore; 1442 } 1443 1444 1447 public void compactStorage() { 1448 if (canWrite()) 1449 compact(getBundleStoreRootDir()); 1450 } 1451 1452 1459 private void compact(File directory) { 1460 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 1461 Debug.println("compact(" + directory.getPath() + ")"); } 1463 1464 String list[] = directory.list(); 1465 if (list == null) 1466 return; 1467 1468 int len = list.length; 1469 1470 for (int i = 0; i < len; i++) { 1471 if (DATA_DIR_NAME.equals(list[i])) { 1472 continue; 1473 } 1474 1475 File target = new File(directory, list[i]); 1476 1477 1478 if (!target.isDirectory()) 1479 continue; 1480 File delete = new File(target, ".delete"); 1482 1483 if (delete.exists()) { 1484 1487 if (!rm(target) && !delete.exists()) { 1488 try { 1489 1490 FileOutputStream out = new FileOutputStream(delete); 1491 out.close(); 1492 } catch (IOException e) { 1493 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 1494 Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); } 1496 } 1497 } 1498 } else { 1499 compact(target); 1500 } 1501 } 1502 } 1503 1504 1508 protected File getMetaDataFile() { 1509 return new File(getBundleStoreRootDir(), ".framework"); } 1511 1512 1516 protected static class ParentClassLoader extends ClassLoader { 1517 protected ParentClassLoader() { 1518 super(null); 1519 } 1520 } 1521 1522 1528 protected void updateState(BundleData bundleData, int type) throws BundleException { 1529 if (stateManager == null) { 1530 invalidState = true; 1531 return; 1532 } 1533 State systemState = stateManager.getSystemState(); 1534 switch (type) { 1535 case BundleEvent.UPDATED : 1536 systemState.removeBundle(bundleData.getBundleID()); 1537 case BundleEvent.INSTALLED : 1539 BundleDescription newDescription = stateManager.getFactory().createBundleDescription(systemState, bundleData.getManifest(), bundleData.getLocation(), bundleData.getBundleID()); 1540 systemState.addBundle(newDescription); 1541 break; 1542 case BundleEvent.UNINSTALLED : 1543 systemState.removeBundle(bundleData.getBundleID()); 1544 break; 1545 } 1546 } 1547 1548 1551 public boolean canWrite() { 1552 return true; 1553 } 1554} 1555 | Popular Tags |