Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2006-02-02 21:08:39 +0000
committerThomas Watson2006-02-02 21:08:39 +0000
commit452a71a4901410b0ed7259b2ce95d447787613ed (patch)
tree343d37e01ba71b48809c94e3f3cdb83c40040489 /bundles
parentd46feca470c5042afa502ce9192917bed9fcf246 (diff)
downloadrt.equinox.framework-452a71a4901410b0ed7259b2ce95d447787613ed.tar.gz
rt.equinox.framework-452a71a4901410b0ed7259b2ce95d447787613ed.tar.xz
rt.equinox.framework-452a71a4901410b0ed7259b2ce95d447787613ed.zip
Bug 114968 Replace monolithic EclipseAdaptor impl with a hookable adaptorpost-bug114968-hooks
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/internal/plugins/InstallTests.java2
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/PlatformAdminTest.java58
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/SimpleBundleInstaller.java36
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/SimplePlatformAdmin.java3
-rw-r--r--bundles/org.eclipse.osgi/META-INF/MANIFEST.MF81
-rw-r--r--bundles/org.eclipse.osgi/build.properties3
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/BundleWatcher.java62
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/FrameworkAdaptor.java26
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/util/KeyedElement.java38
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/util/KeyedHashSet.java (renamed from bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/KeyedHashSet.java)121
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java12
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java35
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoader.java1
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoaderProxy.java2
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleRepository.java1
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java13
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/NullPackageSource.java1
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PackageSource.java1
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/launcher/Launcher.java2
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseAdaptor.java503
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseData.java442
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/HookConfigurator.java (renamed from bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/KeyedElement.java)19
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/HookRegistry.java282
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleEntry.java79
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleFile.java183
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirBundleFile.java113
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirZipBundleEntry.java73
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/FileBundleEntry.java92
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/MRUBundleFileList.java142
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/NestedDirBundleFile.java81
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/ZipBundleEntry.java101
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/ZipBundleFile.java285
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/AdaptorHook.java110
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/BundleFileFactoryHook.java34
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/ClassLoadingHook.java97
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/ClassLoadingStatsHook.java79
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/StorageHook.java148
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/BaseClassLoader.java75
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathEntry.java80
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathManager.java572
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/FragmentClasspath.java72
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractBundleData.java846
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractClassLoader.java219
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractFrameworkAdaptor.java1554
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AdaptorElementFactory.java46
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleEntry.java298
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleFile.java597
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleInstaller.java47
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/DefaultClassLoader.java722
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SignedBundle.java65
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SignedBundleSupport.java38
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/BundleResourceHandler.java15
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/BundleURLConnection.java11
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/DefaultPermissionStorage.java349
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultAdaptor.java203
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultBundleData.java89
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultElementFactory.java29
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultLog.java49
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/MetaData.java201
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/protocol/bundleentry/Handler.java10
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/protocol/bundleresource/Handler.java20
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFile.java2
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileInputStream.java8
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileOutputStream.java3
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorMsg.java (renamed from bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AdaptorMsg.java)4
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorUtil.java199
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseClassLoadingHook.java91
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseHookConfigurator.java28
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BasePermissionStorage.java83
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java1111
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorageHook.java302
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleInstall.java131
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUninstall.java68
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUpdate.java154
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader.java237
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/DevClassLoadingHook.java76
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/DevClassPathHelper.java (renamed from bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/DevClassPathHelper.java)2
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/ExternalMessages.properties (renamed from bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/ExternalMessages.properties)0
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/InvalidVersion.java (renamed from bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/InvalidVersion.java)2
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/StateManager.java (renamed from bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/StateManager.java)40
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/SystemBundleData.java (renamed from bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/SystemBundleData.java)68
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/ADAPTOR.MF8
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java982
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseBundleData.java575
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseClassLoader.java407
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseElementFactory.java36
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseStarter.java2
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/BundleStopper.java25
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/CachedManifest.java33
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/ClasspathManifest.java81
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorHook.java210
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMessages.properties (renamed from bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMessages.properties)0
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMsg.java (renamed from bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMsg.java)4
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAppLauncher.java1
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseBundleInstaller.java42
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseClassLoadingHook.java264
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseCommandProvider.java1
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseEnvironmentInfo.java1
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseErrorHandler.java109
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLazyStarter.java159
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLogHook.java125
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseStorageHook.java406
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/Locker_JavaNio.java1
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/PluginConverterImpl.java2
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/PluginParser.java1
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/stats/StatsManager.java56
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/service/datalocation/Location.java1
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/service/localization/BundleLocalization.java2
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/storagemanager/ManagedOutputStream.java1
-rw-r--r--bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/storagemanager/StorageManager.java6
-rw-r--r--bundles/org.eclipse.osgi/hookconfigurators.properties20
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java8
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateDeltaImpl.java1
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java7
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMessages.properties105
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMsg.java139
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/Locker_JavaNio.java1
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFile.java2
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileInputStream.java8
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileOutputStream.java3
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/service/datalocation/Location.java1
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/service/localization/BundleLocalization.java2
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/storagemanager/ManagedOutputStream.java1
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/storagemanager/StorageManager.java6
124 files changed, 8243 insertions, 7779 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/internal/plugins/InstallTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/internal/plugins/InstallTests.java
index 83f2914e8..9fcf5d4d4 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/internal/plugins/InstallTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/internal/plugins/InstallTests.java
@@ -68,7 +68,7 @@ public class InstallTests extends TestCase {
try {
assertEquals("1.0", "bundle02", installed.getSymbolicName());
assertEquals("1.1", Bundle.INSTALLED, installed.getState());
- assertEquals("1.2", "2.0", installed.getHeaders().get(Constants.BUNDLE_VERSION));
+ assertEquals("1.2", new Version("2.0"), new Version((String) installed.getHeaders().get(Constants.BUNDLE_VERSION)));
} finally {
// clean-up
installed.uninstall();
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/PlatformAdminTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/PlatformAdminTest.java
index 26f645618..d71ddf1db 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/PlatformAdminTest.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/PlatformAdminTest.java
@@ -13,7 +13,6 @@ package org.eclipse.osgi.tests.services.resolver;
import java.io.*;
import junit.framework.Test;
import junit.framework.TestSuite;
-import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.State;
import org.osgi.framework.BundleException;
@@ -51,63 +50,6 @@ public class PlatformAdminTest extends AbstractStateTest {
newState = original.getFactory().createState(original);
assertEquals("2", original, newState);
}
-
- public void testCommit() {
- final String A1_LOCATION = "org.eclipse.a";
- final String A1_MANIFEST = "Bundle-SymbolicName: org.eclipse.a\n" + "Bundle-Version: 1.0.0\n" + "Export-Package: org.eclipse.package1,org.eclipse.package2\n" + ";Import-Package: org.eclipse.package3";
- final String B1_LOCATION = "org.eclipse.b";
- final String B1_MANIFEST = "Bundle-SymbolicName: org.eclipse.b\n" + "Bundle-Version: 1.0.0\n" + "Provide-Package: org.eclipse.b.package1,org.eclipse.b.package2,org.eclipse.b.package3\n" + "Export-Package: org.eclipse.package3";
- final String C1_LOCATION = "org.eclipse.c";
- final String C1_MANIFEST = "Bundle-SymbolicName: org.eclipse.c\n" + "Bundle-Version: 1.0.0\n" + "Required-Bundle: org.eclipse.b";
- final String D1_LOCATION = "org.eclipse.d";
- final String D1_MANIFEST = "Bundle-SymbolicName: org.eclipse.d\n" + "Bundle-Version: 1.0.0";
- State state = platformAdmin.getState();
- BundleDescription a1 = null;
- BundleDescription b1 = null;
- BundleDescription c1 = null;
- BundleDescription d1 = null;
- try {
- a1 = state.getFactory().createBundleDescription(parseManifest(A1_MANIFEST), A1_LOCATION, 3);
- b1 = state.getFactory().createBundleDescription(parseManifest(B1_MANIFEST), B1_LOCATION, 1);
- c1 = state.getFactory().createBundleDescription(parseManifest(C1_MANIFEST), C1_LOCATION, 2);
- d1 = state.getFactory().createBundleDescription(parseManifest(D1_MANIFEST), D1_LOCATION, 4);
- } catch (BundleException e) {
- fail("0.0", e);
- }
- state.addBundle(b1);
- state.addBundle(c1);
- assertEquals("0.5", 2, state.getBundles().length);
- try {
- platformAdmin.commit(state);
- } catch (BundleException e) {
- fail("1.0 - " + e.toString());
- }
- assertEquals("2.0", 2, platformAdmin.getState().getBundles().length);
- State staleState = platformAdmin.getState();
- state = platformAdmin.getState();
- state.addBundle(a1);
- try {
- platformAdmin.commit(state);
- } catch (BundleException e) {
- fail("3.0 - " + e.toString());
- }
- assertEquals("4.0", 3, platformAdmin.getState().getBundles().length);
- staleState.addBundle(d1);
- try {
- platformAdmin.commit(staleState);
- fail("5.0");
- } catch (BundleException e) {
- // that is ok, it should have failed
- }
- state = platformAdmin.getState();
- assertNotNull("5.9", state.removeBundle(1));
- try {
- platformAdmin.commit(state);
- } catch (BundleException e) {
- fail("6.0 - " + e.toString());
- }
- assertEquals("7.0", 2, platformAdmin.getState().getBundles().length);
- }
}
//TODO tests to enable
//testFragmentUpdateNoVersionChanged()
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/SimpleBundleInstaller.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/SimpleBundleInstaller.java
deleted file mode 100644
index e5a41070a..000000000
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/SimpleBundleInstaller.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.osgi.tests.services.resolver;
-
-import org.eclipse.osgi.framework.adaptor.core.BundleInstaller;
-import org.eclipse.osgi.service.resolver.BundleDescription;
-import org.eclipse.osgi.service.resolver.State;
-import org.osgi.framework.BundleException;
-
-public class SimpleBundleInstaller implements BundleInstaller {
- private State state;
-
- public SimpleBundleInstaller(State state) {
- this.state = state;
- }
-
- public void installBundle(BundleDescription toInstall) throws BundleException {
- state.addBundle(toInstall);
- }
-
- public void uninstallBundle(BundleDescription toUninstall) throws BundleException {
- state.removeBundle(toUninstall);
- }
-
- public void updateBundle(BundleDescription toUpdate) throws BundleException {
- //TODO
- }
-}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/SimplePlatformAdmin.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/SimplePlatformAdmin.java
index 8dd67e8fd..10b6aff1d 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/SimplePlatformAdmin.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/services/resolver/SimplePlatformAdmin.java
@@ -11,13 +11,12 @@
package org.eclipse.osgi.tests.services.resolver;
import java.io.File;
-import org.eclipse.osgi.framework.adaptor.core.StateManager;
+import org.eclipse.osgi.internal.baseadaptor.StateManager;
import org.osgi.framework.BundleContext;
public class SimplePlatformAdmin extends StateManager {
public SimplePlatformAdmin(File bundleRootDir, BundleContext context) {
super(new File(bundleRootDir, ".state"), new File(bundleRootDir, ".lazy"), context); //$NON-NLS-1$//$NON-NLS-2$
createSystemState();
- setInstaller(new SimpleBundleInstaller(getSystemState()));
}
}
diff --git a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
index a88f6c61d..8b43cb9e7 100644
--- a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
@@ -1,44 +1,47 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
-Export-Package: org.osgi.framework; version=1.3,
- org.osgi.service.packageadmin; version=1.2,
- org.osgi.service.permissionadmin; version=1.2,
- org.osgi.service.condpermadmin; version=1.0,
- org.osgi.service.url; version=1.0,
- org.osgi.service.startlevel; version=1.0,
- org.osgi.util.tracker; version=1.3.1,
- org.eclipse.osgi.event; version=1.0,
- org.eclipse.osgi.framework.console; version=1.0,
- org.eclipse.osgi.framework.eventmgr; version=1.0,
- org.eclipse.osgi.framework.log; version=1.0,
- org.eclipse.osgi.service.debug; version=1.0,
- org.eclipse.osgi.service.datalocation; version=1.0,
- org.eclipse.osgi.service.environment; version=1.0,
- org.eclipse.osgi.service.localization; version=1.0,
- org.eclipse.osgi.service.pluginconversion; version=1.0,
- org.eclipse.osgi.service.resolver; version=1.0,
- org.eclipse.osgi.service.runnable; version=1.0,
- org.eclipse.osgi.service.urlconversion; version=1.0,
- org.eclipse.osgi.storagemanager; version=1.0,
- org.eclipse.osgi.util; version=1.0,
- org.eclipse.core.runtime.adaptor; x-friends:=org.eclipse.core.runtime,
- org.eclipse.core.runtime.internal.adaptor; x-internal:=true,
- org.eclipse.core.runtime.internal.stats; x-friends:="org.eclipse.core.runtime, org.eclipse.core.tools",
- org.eclipse.osgi.framework.adaptor; x-internal:=true,
- org.eclipse.osgi.framework.adaptor.core; x-internal:=true,
- org.eclipse.osgi.framework.debug; x-internal:=true,
- org.eclipse.osgi.framework.internal.core; x-internal:=true,
- org.eclipse.osgi.framework.internal.defaultadaptor; x-internal:=true,
- org.eclipse.osgi.framework.internal.protocol; x-internal:=true,
- org.eclipse.osgi.framework.internal.protocol.bundleentry; x-internal:=true,
- org.eclipse.osgi.framework.internal.protocol.bundleresource; x-internal:=true,
- org.eclipse.osgi.framework.internal.protocol.reference; x-internal:=true,
- org.eclipse.osgi.framework.internal.reliablefile; x-internal:=true,
- org.eclipse.osgi.framework.launcher; x-internal:=true,
- org.eclipse.osgi.framework.util; x-internal:=true,
- org.eclipse.osgi.internal.module; x-internal:=true,
- org.eclipse.osgi.internal.resolver; x-internal:=true,
- org.eclipse.osgi.internal.profile; x-internal:=true
+Export-Package: org.eclipse.osgi.event;version="1.0",
+ org.eclipse.osgi.framework.console;version="1.0",
+ org.eclipse.osgi.framework.eventmgr;version="1.0",
+ org.eclipse.osgi.framework.log;version="1.0",
+ org.eclipse.osgi.service.datalocation;version="1.0",
+ org.eclipse.osgi.service.debug;version="1.0",
+ org.eclipse.osgi.service.environment;version="1.0",
+ org.eclipse.osgi.service.localization;version="1.0",
+ org.eclipse.osgi.service.pluginconversion;version="1.0",
+ org.eclipse.osgi.service.resolver;version="1.0",
+ org.eclipse.osgi.service.runnable;version="1.0",
+ org.eclipse.osgi.service.urlconversion;version="1.0",
+ org.eclipse.osgi.storagemanager;version="1.0",
+ org.eclipse.osgi.util;version="1.0",
+ org.osgi.framework;version="1.3",
+ org.osgi.service.condpermadmin;version="1.0",
+ org.osgi.service.packageadmin;version="1.2",
+ org.osgi.service.permissionadmin;version="1.2",
+ org.osgi.service.startlevel;version="1.0",
+ org.osgi.service.url;version="1.0",
+ org.osgi.util.tracker;version="1.3.1",
+ org.eclipse.core.runtime.adaptor;x-friends:="org.eclipse.core.runtime",
+ org.eclipse.core.runtime.internal.adaptor;x-internal:=true,
+ org.eclipse.core.runtime.internal.stats;x-friends:="org.eclipse.core.runtime,org.eclipse.core.tools",
+ org.eclipse.osgi.baseadaptor;x-internal:=true,
+ org.eclipse.osgi.baseadaptor.bundlefile;x-internal:=true,
+ org.eclipse.osgi.baseadaptor.hooks;x-internal:=true,
+ org.eclipse.osgi.baseadaptor.loader;x-internal:=true,
+ org.eclipse.osgi.framework.adaptor;x-internal:=true,
+ org.eclipse.osgi.framework.debug;x-internal:=true,
+ org.eclipse.osgi.framework.internal.core;x-internal:=true,
+ org.eclipse.osgi.framework.internal.protocol;x-internal:=true,
+ org.eclipse.osgi.framework.internal.protocol.bundleentry;x-internal:=true,
+ org.eclipse.osgi.framework.internal.protocol.bundleresource;x-internal:=true,
+ org.eclipse.osgi.framework.internal.protocol.reference;x-internal:=true,
+ org.eclipse.osgi.framework.internal.reliablefile;x-internal:=true,
+ org.eclipse.osgi.framework.launcher;x-internal:=true,
+ org.eclipse.osgi.framework.util;x-internal:=true,
+ org.eclipse.osgi.internal.baseadaptor;x-internal:=true,
+ org.eclipse.osgi.internal.module;x-internal:=true,
+ org.eclipse.osgi.internal.profile;x-internal:=true,
+ org.eclipse.osgi.internal.resolver;x-internal:=true
Export-Service: org.osgi.service.packageadmin.PackageAdmin,
org.osgi.service.permissionadmin.PermissionAdmin,
org.osgi.service.startlevel.StartLevel,
diff --git a/bundles/org.eclipse.osgi/build.properties b/bundles/org.eclipse.osgi/build.properties
index 9b863e150..c452f644b 100644
--- a/bundles/org.eclipse.osgi/build.properties
+++ b/bundles/org.eclipse.osgi/build.properties
@@ -17,6 +17,7 @@ bin.includes = .options,\
META-INF/,\
systembundle.properties,\
*.profile,\
- profile.list
+ profile.list,\
+ hookconfigurators.properties
src.includes = about.html
source.. = osgi/src, core/adaptor/, core/framework/, resolver/src/, defaultAdaptor/src/, eclipseAdaptor/src/, console/src/
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/BundleWatcher.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/BundleWatcher.java
index 99abf1cac..d11a76fcc 100644
--- a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/BundleWatcher.java
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/BundleWatcher.java
@@ -13,8 +13,17 @@ package org.eclipse.osgi.framework.adaptor;
import org.osgi.framework.Bundle;
/**
- * Contains information about activated bundles and acts as the main
- * entry point for logging plugin activity.
+ * Watches bundle lifecyle processes. This interface is different than that of
+ * a BundleLisener because it gets notified before and after all lifecycle
+ * changes. A bundle watcher acts as the main entry point for logging
+ * bundle activity.
+ * <p>
+ * Note that a bundle watcher is always notified of when a lifecycle processes
+ * has ended even in cases where the lifecycle process may have failed. For
+ * example, if activating a bundle fails the {@link #END_ACTIVATION} flag will
+ * still be sent to the bundle watcher to notify them that the activation
+ * process has ended.
+ * </p>
* <p>
* Clients may implement this interface.
* </p>
@@ -22,14 +31,51 @@ import org.osgi.framework.Bundle;
*/
public interface BundleWatcher {
/**
- * Called when a bundle is being activated.
- * @param bundle the bundle being activated.
+ * The install process is beginning for a bundle
+ */
+ public static final int START_INSTALLING = 0x0001;
+ /**
+ * The install process has ended for a bundle
+ */
+ public static final int END_INSTALLING = 0x0002;
+ /**
+ * The activation process is beginning for a bundle
+ */
+ public static final int START_ACTIVATION = 0x0004;
+ /**
+ * The activation process has ended for a bundle
+ */
+ public static final int END_ACTIVATION = 0x0008;
+ /**
+ * The deactivation process is beginning for a bundle
+ */
+ public static final int START_DEACTIVATION = 0x0010;
+ /**
+ * The deactivation process has ended for a bundle
+ */
+ public static final int END_DEACTIVATION = 0x0020;
+ /**
+ * The uninstallation process is beginning for a bundle
+ */
+ public static final int START_UNINSTALLING = 0x0040;
+ /**
+ * The uninstallation process has ended for a bundle
*/
- public void startActivation(Bundle bundle);
+ public static final int END_UNINSTALLING = 0x0080;
/**
- * Called after a bundle has been activated.
- * @param bundle the bundle being activated.
+ * Receives notification that a lifecycle change is going to start or has
+ * ended.
+ * @param bundle the bundle for which the lifecycle change is occurring on.
+ * @param type the type of lifecycle change which is occurring.
+ * @see #START_INSTALLING
+ * @see #END_INSTALLING
+ * @see #START_ACTIVATION
+ * @see #END_ACTIVATION
+ * @see #START_DEACTIVATION
+ * @see #END_DEACTIVATION
+ * @see #START_UNINSTALLING
+ * @see #END_UNINSTALLING
*/
- public void endActivation(Bundle bundle);
+ public void watchBundle(Bundle bundle, int type);
}
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/FrameworkAdaptor.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/FrameworkAdaptor.java
index 64718d9ce..442516cee 100644
--- a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/FrameworkAdaptor.java
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/adaptor/FrameworkAdaptor.java
@@ -214,32 +214,6 @@ public interface FrameworkAdaptor {
public void frameworkStopping(BundleContext context);
/**
- * Gets the value for Export-Package for packages that a FrameworkAdaptor is exporting
- * to the framework. The String returned will be parsed by the framework
- * and the packages specified will be exported by the System Bundle.
- * @return The value for Export-Package that the System Bundle will export or
- * null if none exist.
- */
- public String getExportPackages();
-
- /**
- * Gets the value for Provide-Package for packages that a FrameworkAdaptor is exporting
- * to the framework. The String returned will be parsed by the framework
- * and the packages specified will be exported by the System Bundle.
- * @return The value for Provide-Package that the System Bundle will export or
- * null if none exist.
- */
- public String getProvidePackages();
-
- /**
- * Gets any Service class names that a FrameworkAdaptor is exporting to the
- * framework. The class names returned will be exported by the System Bundle.
- * @return The value of Export-Service that the System Bundle will export or
- * null if none exist
- */
- public String getExportServices();
-
- /**
* Returns the initial bundle start level as maintained by this adaptor
* @return the initial bundle start level
*/
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/util/KeyedElement.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/util/KeyedElement.java
new file mode 100644
index 000000000..6f81a8043
--- /dev/null
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/util/KeyedElement.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.framework.util;
+
+/**
+ * An element of an <code>KeyedHashSet</code>. A KeyedElement privides the key which is used to hash
+ * the elements in an <code>KeyedHashSet</code>.
+ * @see KeyedHashSet
+ */
+// This class was moved from /org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/KeyedElement.java
+public interface KeyedElement {
+ /**
+ * Returns the hash code of the key
+ * @return the hash code of the key
+ */
+ public int getKeyHashCode();
+
+ /**
+ * Compares this element with a specified element
+ * @param other the element to compare with
+ * @return returns true if the specified element equals this element
+ */
+ public boolean compare(KeyedElement other);
+
+ /**
+ * Returns the key for this element
+ * @return the key for this element
+ */
+ public Object getKey();
+}
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/KeyedHashSet.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/util/KeyedHashSet.java
index a1ed4f675..85a6e0417 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/KeyedHashSet.java
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/framework/util/KeyedHashSet.java
@@ -8,36 +8,63 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
-package org.eclipse.osgi.framework.internal.core;
+package org.eclipse.osgi.framework.util;
import java.util.Iterator;
import java.util.NoSuchElementException;
+/**
+ * A set data structure which only accepts {@link KeyedElement} objects as elements of the set.
+ * Unlike typical set implementations this set requires each element to provide its own key. This helps
+ * reduce the overhead of storing the keys of each individual element<p>
+ * This class in not thread safe, clients must ensure synchronization when modifying an object of this type.
+ */
+// This class was moved from /org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/KeyedHashSet.java
public class KeyedHashSet {
- protected static final int MINIMUM_SIZE = 7;
- protected int elementCount = 0;
- protected KeyedElement[] elements;
- protected boolean replace;
+ public static final int MINIMUM_SIZE = 7;
+ int elementCount = 0;
+ KeyedElement[] elements;
+ private boolean replace;
private int capacity;
+ /**
+ * Constructs an KeyedHashSet which allows elements to be replaced and with the minimum initial capacity.
+ */
public KeyedHashSet() {
this(MINIMUM_SIZE, true);
}
+ /**
+ * Constructs an KeyedHashSet with the minimum initial capacity.
+ * @param replace true if this set allows elements to be replaced
+ */
public KeyedHashSet(boolean replace) {
this(MINIMUM_SIZE, replace);
}
+ /**
+ * Constructs an KeyedHashSet which allows elements to be replaced.
+ * @param capacity the initial capacity of this set
+ */
public KeyedHashSet(int capacity) {
this(capacity, true);
}
+ /**
+ * Constructs an KeyedHashSet
+ * @param capacity the initial capacity of this set
+ * @param replace true if this set allows elements to be replaced
+ */
public KeyedHashSet(int capacity, boolean replace) {
elements = new KeyedElement[Math.max(MINIMUM_SIZE, capacity * 2)];
this.replace = replace;
this.capacity = capacity;
}
+ /**
+ * Constructs a new KeyedHashSet and copies to specified KeyedHashSet's contents to the new KeyedHashSet.
+ * @param original the KeyedHashSet to copy
+ */
public KeyedHashSet(KeyedHashSet original) {
elements = new KeyedElement[original.elements.length];
System.arraycopy(original.elements, 0, elements, 0, original.elements.length);
@@ -93,23 +120,50 @@ public class KeyedHashSet {
return add(element);
}
+ /**
+ * Adds the specified list of elements to this set. Some elements may not
+ * get added if the replace flag is set.
+ * @param toAdd the list of elements to add to this set.
+ */
public void addAll(KeyedElement[] toAdd) {
for (int i = 0; i < toAdd.length; i++)
add(toAdd[i]);
}
+ /**
+ * Returns true if the specified element exists in this set.
+ * @param element the requested element
+ * @return true if the specified element exists in this set; false otherwise.
+ */
public boolean contains(KeyedElement element) {
return get(element) != null;
}
+ /**
+ * Returns true if an element with the specified key exists in this set.
+ * @param key the key of the requested element
+ * @return true if an element with the specified key exists in this set; false otherwise
+ */
public boolean containsKey(Object key) {
return getByKey(key) != null;
}
+ /**
+ * Returns all elements that exist in this set
+ * @return all elements that exist in this set
+ */
public KeyedElement[] elements() {
return (KeyedElement[]) elements(new KeyedElement[elementCount]);
}
+ /**
+ * Copies all elements that exist in this set into the specified array. No size
+ * checking is done. If the specified array is to small an ArrayIndexOutOfBoundsException
+ * will be thrown.
+ * @param result the array to copy the existing elements into.
+ * @return the specified array.
+ * @throws ArrayIndexOutOfBoundsException if the specified array is to small.
+ */
public Object[] elements(Object[] result) {
int j = 0;
for (int i = 0; i < elements.length; i++) {
@@ -144,8 +198,9 @@ public class KeyedHashSet {
}
/**
- * Returns the set element with the given id, or null
- * if not found.
+ * Returns the element with the specified key, or null if not found.
+ * @param key the requested element's key
+ * @return the element with the specified key, or null if not found.
*/
public KeyedElement getByKey(Object key) {
if (elementCount == 0)
@@ -175,20 +230,22 @@ public class KeyedHashSet {
}
/**
- * Returns the set element with the given id, or null
- * if not found.
+ * Returns the element which compares to the specified element, or null if not found.
+ * @see KeyedElement#compare(KeyedElement)
+ * @param otherElement the requested element
+ * @return the element which compares to the specified element, or null if not found.
*/
- public KeyedElement get(KeyedElement key) {
+ public KeyedElement get(KeyedElement otherElement) {
if (elementCount == 0)
return null;
- int hash = hash(key);
+ int hash = hash(otherElement);
// search the last half of the array
for (int i = hash; i < elements.length; i++) {
KeyedElement element = elements[i];
if (element == null)
return null;
- if (element.compare(key))
+ if (element.compare(otherElement))
return element;
}
@@ -197,7 +254,7 @@ public class KeyedHashSet {
KeyedElement element = elements[i];
if (element == null)
return null;
- if (element.compare(key))
+ if (element.compare(otherElement))
return element;
}
@@ -205,6 +262,10 @@ public class KeyedHashSet {
return null;
}
+ /**
+ * Returns true if this set is empty
+ * @return true if this set is empty
+ */
public boolean isEmpty() {
return elementCount == 0;
}
@@ -212,6 +273,7 @@ public class KeyedHashSet {
/**
* The element at the given index has been removed so move
* elements to keep the set properly hashed.
+ * @param anIndex the index that has been removed
*/
protected void rehashTo(int anIndex) {
@@ -239,6 +301,11 @@ public class KeyedHashSet {
elements[target] = null;
}
+ /**
+ * Removes the element with the specified key
+ * @param key the requested element's key
+ * @return true if an element was removed
+ */
public boolean removeByKey(Object key) {
if (elementCount == 0)
return false;
@@ -269,6 +336,11 @@ public class KeyedHashSet {
return true;
}
+ /**
+ * Removes the element which compares to the specified element
+ * @param toRemove the requested element to remove
+ * @return true if an element was removed
+ */
public boolean remove(KeyedElement toRemove) {
if (elementCount == 0)
return false;
@@ -307,6 +379,10 @@ public class KeyedHashSet {
return Math.abs(key.hashCode()) % elements.length;
}
+ /**
+ * Removes all of the specified elements from this set
+ * @param toRemove the requested elements to remove
+ */
public void removeAll(KeyedElement[] toRemove) {
for (int i = 0; i < toRemove.length; i++)
remove(toRemove[i]);
@@ -316,6 +392,10 @@ public class KeyedHashSet {
return elementCount > elements.length * 0.75;
}
+ /**
+ * Returns the number of elements in this set
+ * @return the number of elements in this set
+ */
public int size() {
return elementCount;
}
@@ -337,6 +417,10 @@ public class KeyedHashSet {
return result.toString();
}
+ /**
+ * Returns the number of collisions this set currently has
+ * @return the number of collisions this set currently has
+ */
public int countCollisions() {
int result = 0;
int lastHash = 0;
@@ -361,11 +445,15 @@ public class KeyedHashSet {
return result;
}
+ /**
+ * Returns an iterator of elements in this set
+ * @return an iterator of elements in this set
+ */
public Iterator iterator() {
- return new KeyedHashSetIterator();
+ return new EquinoxSetIterator();
}
- class KeyedHashSetIterator implements Iterator {
+ class EquinoxSetIterator implements Iterator {
private int currentIndex = -1;
private int found;
@@ -391,6 +479,9 @@ public class KeyedHashSet {
}
}
+ /**
+ * Clears all elements from this set
+ */
public void clear() {
elements = new KeyedElement[Math.max(MINIMUM_SIZE, capacity * 2)];
elementCount = 0;
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
index 8558f16b3..ed980a171 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
@@ -18,6 +18,7 @@ import java.security.*;
import java.util.*;
import org.eclipse.osgi.framework.adaptor.*;
import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.framework.util.KeyedElement;
import org.eclipse.osgi.service.resolver.*;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
@@ -853,6 +854,11 @@ public abstract class AbstractBundle implements Bundle, Comparable, KeyedElement
* Uninstall worker. Assumes the caller has the state change lock.
*/
protected void uninstallWorkerPrivileged() throws BundleException {
+ if (Debug.DEBUG) {
+ BundleWatcher bundleStats = framework.adaptor.getBundleWatcher();
+ if (bundleStats != null)
+ bundleStats.watchBundle(this, BundleWatcher.START_UNINSTALLING);
+ }
boolean unloaded = false;
//cache the bundle's headers
getHeaders();
@@ -889,6 +895,12 @@ public abstract class AbstractBundle implements Bundle, Comparable, KeyedElement
framework.publishFrameworkEvent(FrameworkEvent.ERROR, this, ee);
}
throw e;
+ } finally {
+ if (Debug.DEBUG) {
+ BundleWatcher bundleStats = framework.adaptor.getBundleWatcher();
+ if (bundleStats != null)
+ bundleStats.watchBundle(this, BundleWatcher.END_UNINSTALLING);
+ }
}
}
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java
index 7e4e3286e..90934114d 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java
@@ -284,7 +284,7 @@ public class BundleHost extends AbstractBundle {
if ((state & (STARTING | ACTIVE)) != 0) {
return;
}
-
+ boolean shouldStart = false;
try {
if (state == INSTALLED) {
if (!framework.packageAdmin.resolveBundles(new Bundle[] {this})) {
@@ -295,15 +295,13 @@ public class BundleHost extends AbstractBundle {
if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
Debug.println("Bundle: Active sl = " + framework.startLevelManager.getStartLevel() + "; Bundle " + getBundleId() + " sl = " + getStartLevel()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
-
- if (getStartLevel() <= framework.startLevelManager.getStartLevel()) {
+ shouldStart = getStartLevel() <= framework.startLevelManager.getStartLevel();
+ if (shouldStart) {
//STARTUP TIMING Start here
if (Debug.DEBUG) {
- if (Debug.MONITOR_ACTIVATION) {
- BundleWatcher bundleStats = framework.adaptor.getBundleWatcher();
- if (bundleStats != null)
- bundleStats.startActivation(this);
- }
+ BundleWatcher bundleStats = framework.adaptor.getBundleWatcher();
+ if (bundleStats != null)
+ bundleStats.watchBundle(this, BundleWatcher.START_ACTIVATION);
if (Debug.DEBUG_BUNDLE_TIME) {
start = System.currentTimeMillis();
System.out.println("Starting " + getSymbolicName()); //$NON-NLS-1$
@@ -341,12 +339,10 @@ public class BundleHost extends AbstractBundle {
}
}
} finally {
- if (Debug.DEBUG && state == ACTIVE) {
- if (Debug.MONITOR_ACTIVATION) {
- BundleWatcher bundleStats = framework.adaptor.getBundleWatcher();
- if (bundleStats != null)
- bundleStats.endActivation(this);
- }
+ if (Debug.DEBUG && shouldStart) {
+ BundleWatcher bundleStats = framework.adaptor.getBundleWatcher();
+ if (bundleStats != null)
+ bundleStats.watchBundle(this, BundleWatcher.END_ACTIVATION);
if (Debug.DEBUG_BUNDLE_TIME)
System.out.println("End starting " + getSymbolicName() + " " + (System.currentTimeMillis() - start)); //$NON-NLS-1$ //$NON-NLS-2$
}
@@ -390,7 +386,11 @@ public class BundleHost extends AbstractBundle {
if ((state & (STOPPING | RESOLVED | INSTALLED)) != 0) {
return;
}
-
+ if (Debug.DEBUG) {
+ BundleWatcher bundleStats = framework.adaptor.getBundleWatcher();
+ if (bundleStats != null)
+ bundleStats.watchBundle(this, BundleWatcher.START_DEACTIVATION);
+ }
state = STOPPING;
framework.publishBundleEvent(BundleEvent.STOPPING, this);
try {
@@ -408,6 +408,11 @@ public class BundleHost extends AbstractBundle {
}
framework.publishBundleEvent(BundleEvent.STOPPED, this);
+ if (Debug.DEBUG) {
+ BundleWatcher bundleStats = framework.adaptor.getBundleWatcher();
+ if (bundleStats != null)
+ bundleStats.watchBundle(this, BundleWatcher.END_DEACTIVATION);
+ }
}
}
}
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoader.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoader.java
index acdfc44a4..4bed0e385 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoader.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoader.java
@@ -18,6 +18,7 @@ import java.security.PrivilegedAction;
import java.util.*;
import org.eclipse.osgi.framework.adaptor.*;
import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.framework.util.KeyedHashSet;
import org.eclipse.osgi.service.resolver.*;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.BundleException;
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoaderProxy.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoaderProxy.java
index 66e561f99..0237635e6 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoaderProxy.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleLoaderProxy.java
@@ -14,9 +14,9 @@ import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
+import org.eclipse.osgi.framework.util.KeyedHashSet;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.*;
-import org.osgi.framework.Bundle;
import org.osgi.service.packageadmin.RequiredBundle;
/*
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleRepository.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleRepository.java
index 22eaca239..8d83cdc17 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleRepository.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleRepository.java
@@ -12,6 +12,7 @@
package org.eclipse.osgi.framework.internal.core;
import java.util.*;
+import org.eclipse.osgi.framework.util.KeyedHashSet;
import org.osgi.framework.Version;
/**
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java
index 2fe6625bd..b8cb98405 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java
@@ -589,7 +589,7 @@ public class Framework implements EventDispatcher, EventPublisher {
* Environment.
*/
protected boolean verifyExecutionEnvironment(Dictionary manifest) throws BundleException {
- if (!Boolean.valueOf(FrameworkProperties.getProperty(Constants.ECLIPSE_EE_INSTALL_VERIFY)).booleanValue())
+ if (!Boolean.valueOf(FrameworkProperties.getProperty(Constants.ECLIPSE_EE_INSTALL_VERIFY, Boolean.TRUE.toString())).booleanValue()) //$NON-NLS-1$
return true;
String headerValue = (String) manifest.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
/* If no required EE is in the manifest return true */
@@ -837,6 +837,11 @@ public class Framework implements EventDispatcher, EventPublisher {
try {
BundleData bundledata = storage.begin();
bundle = createAndVerifyBundle(bundledata);
+ if (Debug.DEBUG) {
+ BundleWatcher bundleStats = adaptor.getBundleWatcher();
+ if (bundleStats != null)
+ bundleStats.watchBundle(bundle, BundleWatcher.START_INSTALLING);
+ }
try {
// Select the native code paths for the bundle;
// this is not done by the adaptor because this
@@ -872,6 +877,12 @@ public class Framework implements EventDispatcher, EventPublisher {
}
bundle.close();
throw error;
+ } finally {
+ if (Debug.DEBUG) {
+ BundleWatcher bundleStats = adaptor.getBundleWatcher();
+ if (bundleStats != null)
+ bundleStats.watchBundle(bundle, BundleWatcher.END_INSTALLING);
+ }
}
/* bundle has been successfully installed */
bundles.add(bundle);
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/NullPackageSource.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/NullPackageSource.java
index e5cd34fed..ea57eefab 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/NullPackageSource.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/NullPackageSource.java
@@ -12,6 +12,7 @@ package org.eclipse.osgi.framework.internal.core;
import java.net.URL;
import java.util.Enumeration;
+import org.eclipse.osgi.framework.util.KeyedHashSet;
/**
* This class is used to optimize finding provided-packages for a bundle.
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PackageSource.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PackageSource.java
index 6be9a89da..699c5e96c 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PackageSource.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/PackageSource.java
@@ -13,6 +13,7 @@ package org.eclipse.osgi.framework.internal.core;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
+import org.eclipse.osgi.framework.util.KeyedElement;
public abstract class PackageSource implements KeyedElement {
protected String id;
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/launcher/Launcher.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/launcher/Launcher.java
index a16093705..5e54721d9 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/launcher/Launcher.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/launcher/Launcher.java
@@ -85,7 +85,7 @@ public class Launcher {
protected boolean console = false;
/** string containing the classname of the adaptor to be used in this framework instance */
- protected String adaptorClassName = "org.eclipse.osgi.framework.internal.defaultadaptor.DefaultAdaptor"; //$NON-NLS-1$
+ protected String adaptorClassName = "org.eclipse.osgi.baseadaptor.BaseAdaptor"; //$NON-NLS-1$
protected final String osgiConsoleClazz = "org.eclipse.osgi.framework.internal.core.FrameworkConsole"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseAdaptor.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseAdaptor.java
new file mode 100644
index 000000000..9107c46dc
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseAdaptor.java
@@ -0,0 +1,503 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor;
+
+import java.io.*;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Properties;
+import org.eclipse.core.runtime.adaptor.LocationManager;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
+import org.eclipse.osgi.baseadaptor.hooks.*;
+import org.eclipse.osgi.framework.adaptor.*;
+import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.framework.internal.core.*;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.framework.log.FrameworkLog;
+import org.eclipse.osgi.framework.log.FrameworkLogEntry;
+import org.eclipse.osgi.internal.baseadaptor.*;
+import org.eclipse.osgi.service.resolver.PlatformAdmin;
+import org.eclipse.osgi.service.resolver.State;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.*;
+
+/**
+ * A Framework adaptor implementation that allows additional functionality to be
+ * hooked in. Hooks are configured using {@link HookConfigurator}
+ * objects. A framework extension may add hook configurators which can be used
+ * to add hooks to the {@link HookRegistry}.
+ * @see HookConfigurator
+ * @see HookRegistry
+ * @see AdaptorHook
+ */
+public class BaseAdaptor implements FrameworkAdaptor{
+ // System property used to set the parent classloader type (boot is the default)
+ private static final String PROP_PARENT_CLASSLOADER = "osgi.parentClassloader"; //$NON-NLS-1$
+ // A parent classloader type that specifies the application classloader
+ private static final String PARENT_CLASSLOADER_APP = "app"; //$NON-NLS-1$
+ // A parent classloader type that specifies the extension classlaoder
+ private static final String PARENT_CLASSLOADER_EXT = "ext"; //$NON-NLS-1$
+ // A parent classloader type that specifies the boot classlaoder
+ private static final String PARENT_CLASSLOADER_BOOT = "boot"; //$NON-NLS-1$
+ // A parent classloader type that specifies the framework classlaoder
+ private static final String PARENT_CLASSLOADER_FWK = "fwk"; //$NON-NLS-1$
+ // The BundleClassLoader parent to use when creating BundleClassLoaders.
+ private static ClassLoader bundleClassLoaderParent;
+ static {
+ // check property for specified parent
+ String type = FrameworkProperties.getProperty(BaseAdaptor.PROP_PARENT_CLASSLOADER, BaseAdaptor.PARENT_CLASSLOADER_BOOT);
+ if (BaseAdaptor.PARENT_CLASSLOADER_FWK.equalsIgnoreCase(type))
+ bundleClassLoaderParent = FrameworkAdaptor.class.getClassLoader();
+ else if (BaseAdaptor.PARENT_CLASSLOADER_APP.equalsIgnoreCase(type))
+ bundleClassLoaderParent = ClassLoader.getSystemClassLoader();
+ else if (BaseAdaptor.PARENT_CLASSLOADER_EXT.equalsIgnoreCase(type)) {
+ ClassLoader appCL = ClassLoader.getSystemClassLoader();
+ if (appCL != null)
+ bundleClassLoaderParent = appCL.getParent();
+ }
+ // default to boot classloader
+ if (bundleClassLoaderParent == null)
+ bundleClassLoaderParent = new ParentClassLoader();
+ }
+
+ // Empty parent classloader. This is used by default as the BundleClassLoader parent.
+ private static class ParentClassLoader extends ClassLoader {
+ protected ParentClassLoader() {
+ super(null);
+ }
+ }
+
+ private EventPublisher eventPublisher;
+ private ServiceRegistry serviceRegistry;
+ private boolean stopping;
+ private HookRegistry hookRegistry;
+ private FrameworkLog log;
+ private BundleContext context;
+ private BaseStorage storage;
+ private BundleWatcher bundleWatcher;
+
+ /**
+ * Constructs a BaseAdaptor.
+ * @param args arguments passed to the adaptor by the framework.
+ */
+ public BaseAdaptor(String[] args) {
+ if (LocationManager.getConfigurationLocation() == null)
+ LocationManager.initializeLocations();
+ hookRegistry = new HookRegistry(this);
+ FrameworkLogEntry[] errors = hookRegistry.initialize();
+ if (errors.length > 0)
+ for (int i = 0; i < errors.length; i++)
+ getFrameworkLog().log(errors[i]);
+ storage = getStorage();
+ // TODO consider passing args to BaseAdaptorHooks
+ }
+
+ /**
+ * This method will call all configured adaptor hooks {@link AdaptorHook#initialize(BaseAdaptor)} method.
+ * @see FrameworkAdaptor#initialize(EventPublisher)
+ */
+ public void initialize(EventPublisher publisher) {
+ this.eventPublisher = publisher;
+ serviceRegistry = new ServiceRegistryImpl();
+ ((ServiceRegistryImpl) serviceRegistry).initialize();
+ // set the adaptor for the adaptor hooks
+ AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
+ for (int i = 0; i < adaptorHooks.length; i++)
+ adaptorHooks[i].initialize(this);
+ }
+
+ /**
+ * @see FrameworkAdaptor#initializeStorage()
+ */
+ public void initializeStorage() throws IOException {
+ storage.initialize(this);
+ }
+
+ /**
+ * @see FrameworkAdaptor#compactStorage()
+ */
+ public void compactStorage() throws IOException {
+ storage.compact();
+ }
+
+ /**
+ * This method will call all the configured adaptor hook {@link AdaptorHook#addProperties(Properties)} methods.
+ * @see FrameworkAdaptor#getProperties()
+ */
+ public Properties getProperties() {
+ Properties props = new Properties();
+ String resource = FrameworkProperties.getProperty(Constants.OSGI_PROPERTIES, Constants.DEFAULT_OSGI_PROPERTIES);
+ try {
+ InputStream in = null;
+ File file = new File(resource);
+ if (file.exists())
+ in = new FileInputStream(file);
+ if (in == null)
+ in = getClass().getResourceAsStream(resource);
+ if (in != null) {
+ try {
+ props.load(new BufferedInputStream(in));
+ } finally {
+ try {
+ in.close();
+ } catch (IOException ee) {
+ // nothing to do
+ }
+ }
+ } else {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("Skipping osgi.properties: " + resource); //$NON-NLS-1$
+ }
+ } catch (IOException e) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("Unable to load osgi.properties: " + e.getMessage()); //$NON-NLS-1$
+ }
+ // add the storage properties
+ storage.addProperties(props);
+ // add the properties from each adaptor hook
+ AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
+ for (int i = 0; i < adaptorHooks.length; i++)
+ adaptorHooks[i].addProperties(props);
+ return props;
+ }
+
+ /**
+ * @see FrameworkAdaptor#getInstalledBundles()
+ */
+ public BundleData[] getInstalledBundles() {
+ return storage.getInstalledBundles();
+ }
+
+ /**
+ * This method will call each configured adaptor hook {@link AdaptorHook#mapLocationToURLConnection(String)} method
+ * until one returns a non-null value. If none of the adaptor hooks return a non-null value then the
+ * string is used to construct a new URL object to open a new url connection.
+ *
+ * @see FrameworkAdaptor#mapLocationToURLConnection(String)
+ */
+ public URLConnection mapLocationToURLConnection(String location) throws BundleException {
+ try {
+ URLConnection result = null;
+ // try the adaptor hooks first;
+ AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
+ for (int i = 0; i < adaptorHooks.length; i++) {
+ result = adaptorHooks[i].mapLocationToURLConnection(location);
+ if (result != null)
+ return result;
+ }
+ // just do the default
+ return (new URL(location).openConnection());
+ } catch (IOException e) {
+ throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_URL_CREATE_EXCEPTION, location), e);
+ }
+ }
+
+ /**
+ * @see FrameworkAdaptor#installBundle(String, URLConnection)
+ */
+ public BundleOperation installBundle(String location, URLConnection source) {
+ return storage.installBundle(location, source);
+ }
+
+ /**
+ * @see FrameworkAdaptor#updateBundle(BundleData, URLConnection)
+ */
+ public BundleOperation updateBundle(BundleData bundledata, URLConnection source) {
+ return storage.updateBundle((BaseData) bundledata, source);
+ }
+
+ /**
+ * @see FrameworkAdaptor#uninstallBundle(BundleData)
+ */
+ public BundleOperation uninstallBundle(BundleData bundledata) {
+ return storage.uninstallBundle((BaseData) bundledata);
+ }
+
+ /**
+ * @see FrameworkAdaptor#getTotalFreeSpace()
+ */
+ public long getTotalFreeSpace() throws IOException {
+ return storage.getFreeSpace();
+ }
+
+ /**
+ * @see FrameworkAdaptor#getPermissionStorage()
+ */
+ public PermissionStorage getPermissionStorage() throws IOException {
+ return storage.getPermissionStorage();
+ }
+
+ /**
+ * @see FrameworkAdaptor#getServiceRegistry()
+ */
+ public ServiceRegistry getServiceRegistry() {
+ return serviceRegistry;
+ }
+
+ /**
+ * This method calls all the configured adaptor hook {@link AdaptorHook#frameworkStart(BundleContext)} methods.
+ * @see FrameworkAdaptor#frameworkStart(BundleContext)
+ */
+ public void frameworkStart(BundleContext fwContext) throws BundleException {
+ this.context = fwContext;
+ stopping = false;
+ BundleResourceHandler.setContext(fwContext);
+ // always start the storage first
+ storage.frameworkStart(fwContext);
+ AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
+ for (int i = 0; i < adaptorHooks.length; i++)
+ adaptorHooks[i].frameworkStart(fwContext);
+ }
+
+ /**
+ * This method calls all the configured adaptor hook {@link AdaptorHook#frameworkStop(BundleContext)} methods.
+ * @see FrameworkAdaptor#frameworkStop(BundleContext)
+ */
+ public void frameworkStop(BundleContext fwContext) throws BundleException {
+ // first inform all configured adaptor hooks
+ AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
+ for (int i = 0; i < adaptorHooks.length; i++)
+ adaptorHooks[i].frameworkStop(fwContext);
+ // stop the storage last
+ storage.frameworkStop(fwContext);
+ fwContext = null;
+ }
+
+ /**
+ * This method calls all the configured adaptor hook {@link AdaptorHook#frameworkStopping(BundleContext)} methods.
+ * @see FrameworkAdaptor#frameworkStopping(BundleContext)
+ */
+ public void frameworkStopping(BundleContext fwContext) {
+ stopping = true;
+ // always tell storage of stopping first
+ storage.frameworkStopping(fwContext);
+ // inform all configured adaptor hooks last
+ AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
+ for (int i = 0; i < adaptorHooks.length; i++)
+ adaptorHooks[i].frameworkStopping(fwContext);
+ }
+
+ /**
+ * @see FrameworkAdaptor#getInitialBundleStartLevel()
+ */
+ public int getInitialBundleStartLevel() {
+ return storage.getInitialBundleStartLevel();
+ }
+
+ /**
+ * @see FrameworkAdaptor#setInitialBundleStartLevel(int)
+ */
+ public void setInitialBundleStartLevel(int value) {
+ storage.setInitialBundleStartLevel(value);
+ }
+
+ /**
+ * This method calls all configured adaptor hook {@link AdaptorHook#createFrameworkLog()} methods
+ * until the first one returns a non-null value. If none of the adaptor hooks return a non-null
+ * value then a framework log implementation which does nothing is returned.
+ * @see FrameworkAdaptor#getFrameworkLog()
+ */
+ public FrameworkLog getFrameworkLog() {
+ if (log != null)
+ return log;
+ AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
+ for (int i = 0; i < adaptorHooks.length; i++) {
+ log = adaptorHooks[i].createFrameworkLog();
+ if (log != null)
+ return log;
+ }
+ log = new FrameworkLog() {
+ public void log(FrameworkEvent frameworkEvent) {
+ log(new FrameworkLogEntry(frameworkEvent.getBundle().getSymbolicName() == null ? frameworkEvent.getBundle().getLocation() : frameworkEvent.getBundle().getSymbolicName(), FrameworkLogEntry.ERROR, 0, "FrameworkEvent.ERROR", 0, frameworkEvent.getThrowable(), null)); //$NON-NLS-1$
+ }
+
+ public void log(FrameworkLogEntry logEntry) {
+ System.err.print(logEntry.getEntry() + " "); //$NON-NLS-1$
+ System.err.println(logEntry.getMessage());
+ if (logEntry.getThrowable() != null)
+ logEntry.getThrowable().printStackTrace(System.err);
+ }
+
+ public void setWriter(Writer newWriter, boolean append) {
+ // do nothing
+ }
+
+ public void setFile(File newFile, boolean append) throws IOException {
+ // do nothing
+ }
+
+ public File getFile() {
+ // do nothing
+ return null;
+ }
+
+ public void setConsoleLog(boolean consoleLog) {
+ // do nothing
+ }
+
+ public void close() {
+ // do nothing
+ }
+ };
+ return log;
+ }
+
+ /**
+ * @see FrameworkAdaptor#createSystemBundleData()
+ */
+ public BundleData createSystemBundleData() throws BundleException {
+ return new SystemBundleData(this);
+ }
+
+ /**
+ * @see FrameworkAdaptor#getBundleWatcher()
+ */
+ public BundleWatcher getBundleWatcher() {
+ if (bundleWatcher != null)
+ return bundleWatcher;
+ final BundleWatcher[] watchers = hookRegistry.getWatchers();
+ if (watchers.length == 0)
+ return null;
+ bundleWatcher = new BundleWatcher() {
+ public void watchBundle(Bundle bundle, int type) {
+ for (int i = 0; i < watchers.length; i++)
+ watchers[i].watchBundle(bundle, type);
+ }
+ };
+ return bundleWatcher;
+ }
+
+ /**
+ * @see FrameworkAdaptor#getPlatformAdmin()
+ */
+ public PlatformAdmin getPlatformAdmin() {
+ return storage.getStateManager();
+ }
+
+ /**
+ * @see FrameworkAdaptor#getState()
+ */
+ public State getState() {
+ return storage.getStateManager().getSystemState();
+ }
+
+ /**
+ * This method calls all the configured classloading hooks {@link ClassLoadingHook#getBundleClassLoaderParent()} methods
+ * until one returns a non-null value.
+ * @see FrameworkAdaptor#getBundleClassLoaderParent()
+ */
+ public ClassLoader getBundleClassLoaderParent() {
+ // ask the configured adaptor hooks first
+ ClassLoader result = null;
+ ClassLoadingHook[] cpManagerHooks = getHookRegistry().getClassLoadingHooks();
+ for (int i = 0; i < cpManagerHooks.length; i++) {
+ result = cpManagerHooks[i].getBundleClassLoaderParent();
+ if (result != null)
+ return result;
+ }
+ // none of the configured adaptor hooks gave use a parent loader; use the default
+ return bundleClassLoaderParent;
+ }
+
+ /**
+ * This method calls all the configured adaptor hooks {@link AdaptorHook#handleRuntimeError(Throwable)} methods.
+ * @see FrameworkAdaptor#handleRuntimeError(Throwable)
+ */
+ public void handleRuntimeError(Throwable error) {
+ AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
+ for (int i = 0; i < adaptorHooks.length; i++)
+ adaptorHooks[i].handleRuntimeError(error);
+ }
+
+ /**
+ * This method calls all the configured adaptor hooks {@link AdaptorHook#matchDNChain(String, String[])} methods
+ * until one returns a true value.
+ * @see FrameworkAdaptor#matchDNChain(String, String[])
+ */
+ public boolean matchDNChain(String pattern, String[] dnChain) {
+ AdaptorHook[] adaptorHooks = getHookRegistry().getAdaptorHooks();
+ for (int i = 0; i < adaptorHooks.length; i++)
+ if (adaptorHooks[i].matchDNChain(pattern, dnChain))
+ return true;
+ return false;
+ }
+
+ /**
+ * Returns true if the {@link #frameworkStopping(BundleContext)} method has been called
+ * @return true if the framework is stopping
+ */
+ public boolean isStopping() {
+ return stopping;
+ }
+
+ /**
+ * Returns the event publisher for this BaseAdaptor
+ * @return the event publisher for this BaseAdaptor
+ */
+ public EventPublisher getEventPublisher() {
+ return eventPublisher;
+ }
+
+ /**
+ * Returns the <code>HookRegistry</code> object for this adaptor.
+ * @return the <code>HookRegistry</code> object for this adaptor.
+ */
+ public HookRegistry getHookRegistry() {
+ return hookRegistry;
+ }
+
+ /**
+ * Returns the system bundle's context
+ * @return the system bundle's context
+ */
+ public BundleContext getContext() {
+ return context;
+ }
+
+ /**
+ * Creates a bundle file object for the given content and base data.
+ * This method must delegate to each configured bundle file factory
+ * {@link BundleFileFactoryHook#createBundleFile(Object, BaseData, boolean)} method until one
+ * factory returns a non-null value. If no bundle file factory returns a non-null value
+ * then the the default behavior will be performed. <p>
+ * If the specified content is <code>null</code> then the base content of the specified
+ * bundledata must be found before calling any bundle file factories.
+ * @param content The object which contains the content of a bundle file. A value of
+ * <code>null</code> indicates that the storage must find the base content for the
+ * specified BaseData.
+ * @param data The BaseData associated with the content
+ * @return a BundleFile object.
+ * @throws IOException if an error occured while creating the BundleFile
+ */
+ public BundleFile createBundleFile(Object content, BaseData data) throws IOException {
+ return storage.createBundleFile(content, data);
+ }
+
+ /**
+ * Returns true if the persistent storage is read-only
+ * @return true if the persistent storage is read-only
+ */
+ public boolean isReadOnly() {
+ return storage.isReadOnly();
+ }
+
+ /*
+ * This is an experimental method to allow adaptors to replace the storage implementation by
+ * extending BaseAdaptor and overriding this method. This method is experimental.
+ * @return a base storage object.
+ */
+ protected BaseStorage getStorage() {
+ if (storage == null)
+ storage = BaseStorage.getInstance();
+ return storage;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseData.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseData.java
new file mode 100644
index 000000000..5e21c088a
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseData.java
@@ -0,0 +1,442 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
+import org.eclipse.osgi.baseadaptor.hooks.*;
+import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
+import org.eclipse.osgi.framework.adaptor.*;
+import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.framework.internal.protocol.bundleentry.Handler;
+import org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader;
+import org.eclipse.osgi.util.ManifestElement;
+import org.osgi.framework.*;
+
+/**
+ * The BundleData implementation used by the BaseAdaptor.
+ * @see BaseAdaptor
+ * @see BundleData
+ * @see StorageHook
+ * @see ClassLoadingHook
+ */
+public class BaseData implements BundleData {
+ private long id;
+ private BaseAdaptor adaptor;
+ private Bundle bundle;
+ private int startLevel = -1;
+ private int status = 0;
+ private StorageHook[] storageHooks;
+ private String location;
+ private long lastModified;
+ protected BundleFile bundleFile;
+ private boolean dirty = false;
+ protected Dictionary manifest;
+
+ ///////////////////// Begin values from Manifest /////////////////////
+ private String symbolicName;
+ private Version version;
+ private String activator;
+ private String classpath;
+ private String executionEnvironment;
+ private String dynamicImports;
+ private int type;
+
+ ///////////////////// End values from Manifest /////////////////////
+
+ /**
+ * Constructs a new BaseData with the specified id for the specified adaptor
+ * @param id the id of the BaseData
+ * @param adaptor the adaptor of the BaseData
+ */
+ public BaseData(long id, BaseAdaptor adaptor) {
+ this.id = id;
+ this.adaptor = adaptor;
+ }
+
+ /**
+ * This method calls all the configured class loading hooks {@link ClassLoadingHook#createClassLoader(ClassLoader, ClassLoaderDelegate, BundleProtectionDomain, BaseData, String[])}
+ * methods until on returns a non-null value. If none of the class loading hooks returns a non-null value
+ * then the default classloader implementation is used. <p>
+ * After the classloader is created all configured class loading hooks
+ * {@link ClassLoadingHook#initializedClassLoader(BaseClassLoader, BaseData)} methods are called.
+ * @see BundleData#createClassLoader(ClassLoaderDelegate, BundleProtectionDomain, String[])
+ */
+ public BundleClassLoader createClassLoader(ClassLoaderDelegate delegate, BundleProtectionDomain domain, String[] bundleclasspath) {
+ ClassLoadingHook[] hooks = adaptor.getHookRegistry().getClassLoadingHooks();
+ ClassLoader parent = adaptor.getBundleClassLoaderParent();
+ BaseClassLoader cl = null;
+ for (int i = 0; i < hooks.length && cl == null; i++)
+ cl = hooks[i].createClassLoader(parent, delegate, domain, this, bundleclasspath);
+ if (cl == null)
+ cl = new DefaultClassLoader(parent, delegate, domain, this, bundleclasspath);
+ for (int i = 0; i < hooks.length; i++)
+ hooks[i].initializedClassLoader(cl, this);
+ return cl;
+ }
+
+ public final URL getEntry(String path) {
+ BundleEntry entry = getBundleFile().getEntry(path);
+ if (entry == null)
+ return null;
+ if (path.length() == 0 || path.charAt(0) != '/')
+ path = path = '/' + path;
+ try {
+ //use the constant string for the protocol to prevent duplication
+ return new URL(Constants.OSGI_ENTRY_URL_PROTOCOL, Long.toString(id), 0, path, new Handler(entry));
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }
+
+ public final Enumeration getEntryPaths(String path) {
+ return getBundleFile().getEntryPaths(path);
+ }
+
+ /**
+ * This method calls each configured classloading hook {@link ClassLoadingHook#findLibrary(BaseData, String)} method
+ * until the first one returns a non-null value.
+ * @see BundleData#findLibrary(String)
+ */
+ public String findLibrary(String libname) {
+ ClassLoadingHook[] hooks = adaptor.getHookRegistry().getClassLoadingHooks();
+ String result = null;
+ for (int i = 0; i < hooks.length; i++) {
+ result = hooks[i].findLibrary(this, libname);
+ if (result != null)
+ return result;
+ }
+ return result;
+ }
+
+ public void installNativeCode(String[] nativepaths) throws BundleException {
+ adaptor.getStorage().installNativeCode(this, nativepaths);
+ }
+
+ public File getDataFile(String path) {
+ return adaptor.getStorage().getDataFile(this, path);
+ }
+
+ public Dictionary getManifest() throws BundleException {
+ if (manifest == null)
+ manifest = adaptor.getStorage().loadManifest(this);
+ return manifest;
+ }
+
+ public long getBundleID() {
+ return id;
+ }
+
+ public final String getLocation() {
+ return location;
+ }
+
+ /**
+ * Sets the location of this bundledata
+ * @param location the location of this bundledata
+ */
+ public final void setLocation(String location) {
+ this.location = location;
+ }
+
+ public final long getLastModified() {
+ return lastModified;
+ }
+
+ /**
+ * Sets the last modified time stamp of this bundledata
+ * @param lastModified the last modified time stamp of this bundledata
+ */
+ public final void setLastModified(long lastModified) {
+ this.lastModified = lastModified;
+ }
+
+ public void close() throws IOException {
+ if (bundleFile != null)
+ getBundleFile().close(); // only close the bundleFile if it already exists.
+ }
+
+ public void open() throws IOException {
+ getBundleFile().open();
+ }
+
+ public final void setBundle(Bundle bundle) {
+ this.bundle = bundle;
+ }
+
+ /**
+ * Returns the bundle object of this BaseData
+ * @return the bundle object of this BaseData
+ */
+ public final Bundle getBundle() {
+ return bundle;
+ }
+
+ public int getStartLevel() {
+ return startLevel;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ /**
+ * This method calls each configured storage hook {@link StorageHook#forgetStartLevelChange(int)} method.
+ * If one returns true then this bundledata is not marked dirty.
+ * @see BundleData#setStartLevel(int)
+ */
+ public void setStartLevel(int value) {
+ startLevel = setPersistentData(value, true, startLevel);
+ }
+
+ /**
+ * This method calls each configured storage hook {@link StorageHook#forgetStatusChange(int)} method.
+ * If one returns true then this bundledata is not marked dirty.
+ * @see BundleData#setStatus(int)
+ */
+ public void setStatus(int value) {
+ status = setPersistentData(value, false, status);
+ }
+
+ private int setPersistentData(int value, boolean isStartLevel, int orig) {
+ StorageHook[] hooks = getStorageHooks();
+ for (int i = 0; i < hooks.length; i++)
+ if (isStartLevel) {
+ if (hooks[i].forgetStartLevelChange(value))
+ return value;
+ } else {
+ if (hooks[i].forgetStatusChange(value))
+ return value;
+ }
+ if (value != orig)
+ dirty = true;
+ return value;
+ }
+
+ public void save() throws IOException {
+ adaptor.getStorage().save(this);
+ }
+
+ /**
+ * Returns true if this bundledata is dirty
+ * @return true if this bundledata is dirty
+ */
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ /**
+ * Sets the dirty flag for this BaseData
+ * @param dirty the dirty flag
+ */
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+
+ public final String getSymbolicName() {
+ return symbolicName;
+ }
+
+ /**
+ * Sets the symbolic name of this BaseData
+ * @param symbolicName the symbolic name
+ */
+ public final void setSymbolicName(String symbolicName) {
+ this.symbolicName = symbolicName;
+ }
+
+ public final Version getVersion() {
+ return version;
+ }
+
+ /**
+ * Sets the version of this BaseData
+ * @param version the version
+ */
+ public final void setVersion(Version version) {
+ this.version = version;
+ }
+
+ public final int getType() {
+ return type;
+ }
+
+ /**
+ * Sets the type of this BaseData
+ * @param type the type
+ */
+ public final void setType(int type) {
+ this.type = type;
+ }
+
+ public final String[] getClassPath() throws BundleException {
+ ManifestElement[] classpathElements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, classpath);
+ return getClassPath(classpathElements);
+ }
+
+ // TODO make classpath a String[] instead of saving a comma separated string.
+ public String getClassPathString() {
+ return classpath;
+ }
+
+ //TODO make classpath a String[] instead of saving a comma separated string.
+ public void setClassPathString(String classpath) {
+ this.classpath = classpath;
+ }
+
+ public final String getActivator() {
+ return activator;
+ }
+
+ /**
+ * Sets the activator of this BaseData
+ * @param activator the activator
+ */
+ public final void setActivator(String activator) {
+ this.activator = activator;
+ }
+
+ public final String getExecutionEnvironment() {
+ return executionEnvironment;
+ }
+
+ /**
+ * Sets the execution environment of this BaseData
+ * @param executionEnvironment the execution environment
+ */
+ public void setExecutionEnvironment(String executionEnvironment) {
+ this.executionEnvironment = executionEnvironment;
+ }
+
+ public final String getDynamicImports() {
+ return dynamicImports;
+ }
+
+ /**
+ * Sets the dynamic imports of this BaseData
+ * @param dynamicImports the dynamic imports
+ */
+ public void setDynamicImports(String dynamicImports) {
+ this.dynamicImports = dynamicImports;
+ }
+
+ /**
+ * This method calls each configured storage hook {@link StorageHook#matchDNChain(String)} method
+ * until one returns true. If no configured storage hook returns true then false is returned.
+ * @see BundleData#matchDNChain(String)
+ */
+ public final boolean matchDNChain(String pattern) {
+ StorageHook[] hooks = getStorageHooks();
+ for (int i = 0; i < hooks.length; i++)
+ if (hooks[i].matchDNChain(pattern))
+ return true;
+ return false;
+ }
+
+ /**
+ * Returns the adaptor for this BaseData
+ * @return the adaptor
+ */
+ public final BaseAdaptor getAdaptor() {
+ return adaptor;
+ }
+
+ /**
+ * Returns the BundleFile for this BaseData. The first time this method is called the
+ * configured storage {@link BaseAdaptor#createBundleFile(Object, BaseData)} method is called.
+ * @return the BundleFile
+ * @throws IllegalArgumentException
+ */
+ public synchronized BundleFile getBundleFile() throws IllegalArgumentException {
+ if (bundleFile == null)
+ try {
+ bundleFile = adaptor.createBundleFile(null, this);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ return bundleFile;
+ }
+
+ private static String[] getClassPath(ManifestElement[] classpath) {
+ if (classpath == null) {
+ if (Debug.DEBUG && Debug.DEBUG_LOADER)
+ Debug.println(" no classpath"); //$NON-NLS-1$
+ /* create default BundleClassPath */
+ return new String[] {"."}; //$NON-NLS-1$
+ }
+
+ ArrayList result = new ArrayList(classpath.length);
+ for (int i = 0; i < classpath.length; i++) {
+ if (Debug.DEBUG && Debug.DEBUG_LOADER)
+ Debug.println(" found classpath entry " + classpath[i].getValueComponents()); //$NON-NLS-1$
+ String[] paths = classpath[i].getValueComponents();
+ for (int j = 0; j < paths.length; j++) {
+ result.add(paths[j]);
+ }
+ }
+
+ return (String[]) result.toArray(new String[result.size()]);
+ }
+
+ /**
+ * Returns the storage hook which is keyed by the specified key
+ * @param key the key of the storage hook to get
+ * @return the storage hook which is keyed by the specified key
+ */
+ public StorageHook getStorageHook(String key) {
+ if (storageHooks == null)
+ return null;
+ for (int i = 0; i < storageHooks.length; i++)
+ if (storageHooks[i].getKey().equals(key))
+ return storageHooks[i];
+ return null;
+ }
+
+ /**
+ * Sets the instance storage hooks for this base data. This is method
+ * may only be called once for the lifetime of the base data. Once set,
+ * the list of storage hooks remains constant.
+ * @param storageHooks the storage hook to add
+ */
+ public void setStorageHooks(StorageHook[] storageHooks) {
+ if (this.storageHooks != null)
+ return; // only allow this to be set once.
+ this.storageHooks = storageHooks;
+ }
+
+ /**
+ * Returns all the storage hooks associated with this BaseData
+ * @return all the storage hooks associated with this BaseData
+ */
+ public StorageHook[] getStorageHooks() {
+ return storageHooks == null ? new StorageHook[0] : storageHooks;
+ }
+
+ /**
+ * Gets called by BundleFile during {@link BundleFile#getFile(String, boolean)}. This method
+ * will allocate a File object where content of the specified path may be
+ * stored for the current generation of the base data. The returned File object may
+ * not exist if the content has not previously be stored.
+ * @param path the path to the content to extract from the base data
+ * @return a file object where content of the specified path may be stored.
+ */
+ public File getExtractFile(String path) {
+ return adaptor.getStorage().getExtractFile(this, path);
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/KeyedElement.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/HookConfigurator.java
index c92db70e9..453574ceb 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/KeyedElement.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/HookConfigurator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,12 +8,17 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
-package org.eclipse.osgi.framework.internal.core;
-public interface KeyedElement {
- public int getKeyHashCode();
+package org.eclipse.osgi.baseadaptor;
- public boolean compare(KeyedElement other);
-
- public Object getKey();
+/**
+ * A hook configurator is used to add hooks to the hook registry.
+ * @see HookRegistry
+ */
+public interface HookConfigurator {
+ /**
+ * Adds hooks to the specified hook registry.
+ * @param hookRegistry the hook registry used to add hooks
+ */
+ public void addHooks(HookRegistry hookRegistry);
}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/HookRegistry.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/HookRegistry.java
new file mode 100644
index 000000000..bc3f7cdf4
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/HookRegistry.java
@@ -0,0 +1,282 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+import org.eclipse.osgi.baseadaptor.hooks.*;
+import org.eclipse.osgi.framework.adaptor.BundleWatcher;
+import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
+import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
+import org.eclipse.osgi.framework.log.FrameworkLogEntry;
+import org.eclipse.osgi.util.ManifestElement;
+
+/**
+ * The hook registry is used to store all the hooks which are
+ * configured by the hook configurators.
+ * @see HookConfigurator
+ */
+public final class HookRegistry {
+ /**
+ * The hook configurators properties file (&quot;hookconfigurators.properties&quot;) <p>
+ * A framework extension may supply a hook configurators properties file to specify a
+ * list of hook configurators.
+ * @see #HOOK_CONFIGURATORS
+ */
+ public static final String HOOK_CONFIGURATORS_FILE = "hookconfigurators.properties"; //$NON-NLS-1$
+
+ /**
+ * The hook configurators property key (&quot;hookconfigurators.properties&quot;) used in
+ * a hook configurators properties file to specify a comma separated list of fully
+ * qualified hook configurator classes.
+ */
+ public static final String HOOK_CONFIGURATORS = "hook.configurators"; //$NON-NLS-1$
+
+ /**
+ * A system property (&quot;osgi.hook.configurators.include&quot;) used to add additional
+ * hook configurators. This is helpful for configuring optional hook configurators.
+ */
+ public static final String PROP_HOOK_CONFIGURATORS_INCLUDE = "osgi.hook.configurators.include"; //$NON-NLS-1$
+
+ /**
+ * A system property (&quot;osgi.hook.configurators.exclude&quot;) used to exclude
+ * any hook configurators. This is helpful for disabling hook
+ * configurators that is specified in hook configurator properties files.
+ */
+ public static final String PROP_HOOK_CONFIGURATORS_EXCLUDE = "osgi.hook.configurators.exclude"; //$NON-NLS-1$
+
+ /**
+ * A system property (&quot;osgi.hook.configurators&quot;) used to specify the list
+ * of hook configurators. If this property is set then the list of configurators
+ * specified will be the only configurators used.
+ */
+ public static final String PROP_HOOK_CONFIGURATORS = "osgi.hook.configurators"; //$NON-NLS-1$
+
+ private BaseAdaptor adaptor;
+ private boolean readonly = false;
+ private AdaptorHook[] adaptorHooks = new AdaptorHook[0];
+ private BundleWatcher[] watchers = new BundleWatcher[0];
+ private ClassLoadingHook[] classLoadingHooks = new ClassLoadingHook[0];
+ private ClassLoadingStatsHook[] classLoadingStatsHooks = new ClassLoadingStatsHook[0];
+ private StorageHook[] storageHooks = new StorageHook[0];
+ private BundleFileFactoryHook[] bundleFileFactoryHooks = new BundleFileFactoryHook[0];
+
+ public HookRegistry(BaseAdaptor adaptor) {
+ this.adaptor = adaptor;
+ }
+
+ /**
+ * Initializes the hook configurators. The following steps are used to initialize the hook configurators. <p>
+ * 1. Get a list of hook configurators from all hook configurators properties files on the classpath,
+ * add this list to the overall list of hook configurators, remove duplicates. <p>
+ * 2. Get a list of hook configurators from the (&quot;osgi.hook.configurators.include&quot;) system property
+ * and add this list to the overall list of hook configurators, remove duplicates. <p>
+ * 3. Get a list of hook configurators from the (&quot;osgi.hook.configurators.exclude&quot;) system property
+ * and remove this list from the overall list of hook configurators. <p>
+ * 4. Load each hook configurator class, create a new instance, then call the {@link HookConfigurator#addHooks(HookRegistry)} method <p>
+ * 5. Set this HookRegistry object to read only to prevent any other hooks from being added. <p>
+ * @return an array of error log entries that occurred while initializing the hooks
+ */
+ public FrameworkLogEntry[] initialize() {
+ ArrayList configurators = new ArrayList(5);
+ ArrayList errors = new ArrayList(0); // optimistic that no errors will occur
+ mergeFileHookConfigurators(configurators, errors);
+ mergePropertyHookConfigurators(configurators);
+ loadConfigurators(configurators, errors);
+ // set to read-only
+ readonly = true;
+ return (FrameworkLogEntry[]) errors.toArray(new FrameworkLogEntry[errors.size()]);
+ }
+
+ private void mergeFileHookConfigurators(ArrayList configuratorList, ArrayList errors) {
+ ClassLoader cl = getClass().getClassLoader();
+ // get all hook configurators files in your classloader delegation
+ Enumeration hookConfigurators;
+ try {
+ hookConfigurators = cl != null ? cl.getResources(HookRegistry.HOOK_CONFIGURATORS_FILE) : ClassLoader.getSystemResources(HookRegistry.HOOK_CONFIGURATORS_FILE);
+ } catch (IOException e) {
+ errors.add(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, "getResources error on " + HookRegistry.HOOK_CONFIGURATORS_FILE, 0, e, null)); //$NON-NLS-1$
+ return;
+ }
+ while (hookConfigurators.hasMoreElements()) {
+ URL url = (URL) hookConfigurators.nextElement();
+ try {
+ // check each file for a hook.configurators property
+ Properties configuratorProps = new Properties();
+ configuratorProps.load(url.openStream());
+ String hooksValue = configuratorProps.getProperty(HOOK_CONFIGURATORS);
+ if (hooksValue == null)
+ continue;
+ String[] configurators = ManifestElement.getArrayFromList(hooksValue, ","); //$NON-NLS-1$
+ for (int i = 0; i < configurators.length; i++)
+ if (!configuratorList.contains(configurators[i]))
+ configuratorList.add(configurators[i]);
+ } catch (IOException e) {
+ errors.add(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, "error loading: " + url.toExternalForm(), 0, e, null)); //$NON-NLS-1$
+ // ignore and continue to next URL
+ }
+ }
+ }
+
+ private void mergePropertyHookConfigurators(ArrayList configuratorList) {
+ // see if there is a configurators list
+ String[] configurators = ManifestElement.getArrayFromList(FrameworkProperties.getProperty(HookRegistry.PROP_HOOK_CONFIGURATORS), ","); //$NON-NLS-1$
+ if (configurators.length > 0) {
+ configuratorList.clear(); // clear the list, we are only going to use the configurators from the list
+ for (int i = 0; i < configurators.length; i++)
+ if (!configuratorList.contains(configurators[i]))
+ configuratorList.add(configurators[i]);
+ return; // don't do anything else
+ }
+ // Make sure the configurators from the include property are in the list
+ String[] includeConfigurators = ManifestElement.getArrayFromList(FrameworkProperties.getProperty(HookRegistry.PROP_HOOK_CONFIGURATORS_INCLUDE), ","); //$NON-NLS-1$
+ for (int i = 0; i < includeConfigurators.length; i++)
+ if (!configuratorList.contains(includeConfigurators[i]))
+ configuratorList.add(includeConfigurators[i]);
+ // Make sure the configurators from the exclude property are no in the list
+ String[] excludeHooks = ManifestElement.getArrayFromList(FrameworkProperties.getProperty(HookRegistry.PROP_HOOK_CONFIGURATORS_EXCLUDE), ","); //$NON-NLS-1$
+ for (int i = 0; i < excludeHooks.length; i++)
+ configuratorList.remove(excludeHooks[i]);
+ }
+
+ private void loadConfigurators(ArrayList configurators, ArrayList errors) {
+ for (Iterator iHooks = configurators.iterator(); iHooks.hasNext();) {
+ String hookName = (String) iHooks.next();
+ try {
+ Class clazz = Class.forName(hookName);
+ HookConfigurator configurator = (HookConfigurator) clazz.newInstance();
+ configurator.addHooks(this);
+ } catch (Throwable t) {
+ // We expect the follow exeptions may happen; but we need to catch all here
+ // ClassNotFoundException
+ // IllegalAccessException
+ // InstantiationException
+ // ClassCastException
+ errors.add(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, "error loading hook: " + hookName, 0, t, null)); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * Returns the list of configured adaptor hooks.
+ * @return the list of configured adaptor hooks.
+ */
+ public AdaptorHook[] getAdaptorHooks() {
+ return adaptorHooks;
+ }
+
+ /**
+ * Returns the list of configured bundle watchers.
+ * @return the list of configured bundle watchers.
+ */
+ public BundleWatcher[] getWatchers() {
+ return watchers;
+ }
+
+ /**
+ * Returns the list of configured class loading hooks.
+ * @return the list of configured class loading hooks.
+ */
+ public ClassLoadingHook[] getClassLoadingHooks() {
+ return classLoadingHooks;
+ }
+
+ /**
+ * Returns the list of configured class loading stats hooks.
+ * @return the list of configured class loading stats hooks.
+ */
+ public ClassLoadingStatsHook[] getClassLoadingStatsHooks() {
+ return classLoadingStatsHooks;
+ }
+
+ /**
+ * Returns the list of configured storage hooks.
+ * @return the list of configured storage hooks.
+ */
+ public StorageHook[] getStorageHooks() {
+ return storageHooks;
+ }
+
+ /**
+ * Returns the list of configured bundle file factories.
+ * @return the list of configured bundle file factories.
+ */
+ public BundleFileFactoryHook[] getBundleFileFactoryHooks() {
+ return bundleFileFactoryHooks;
+ }
+
+ /**
+ * Adds a adaptor hook to this hook registry.
+ * @param adaptorHook an adaptor hook object.
+ */
+ public void addAdaptorHook(AdaptorHook adaptorHook) {
+ adaptorHooks = (AdaptorHook[]) add(adaptorHook, adaptorHooks, new AdaptorHook[adaptorHooks.length + 1]);
+ }
+
+ /**
+ * Adds a bundle watcher to this hook registry.
+ * @param watcher a bundle watcher object.
+ */
+ public void addWatcher(BundleWatcher watcher) {
+ watchers = (BundleWatcher[]) add(watcher, watchers, new BundleWatcher[watchers.length + 1]);
+ }
+
+ /**
+ * Adds a class loading hook to this hook registry.
+ * @param classLoadingHook a class loading hook object.
+ */
+ public void addClassLoadingHook(ClassLoadingHook classLoadingHook) {
+ classLoadingHooks = (ClassLoadingHook[]) add(classLoadingHook, classLoadingHooks, new ClassLoadingHook[classLoadingHooks.length + 1]);
+ }
+
+ /**
+ * Adds a class loading stats hook to this hook registry.
+ * @param classLoadingStatsHook a class loading hook object.
+ */
+ public void addClassLoadingStatsHook(ClassLoadingStatsHook classLoadingStatsHook) {
+ classLoadingStatsHooks = (ClassLoadingStatsHook[]) add(classLoadingStatsHook, classLoadingStatsHooks, new ClassLoadingStatsHook[classLoadingStatsHooks.length + 1]);
+ }
+
+ /**
+ * Adds a storage hook to this hook registry.
+ * @param storageHook a storage hook object.
+ */
+ public void addStorageHook(StorageHook storageHook) {
+ storageHooks = (StorageHook[]) add(storageHook, storageHooks, new StorageHook[storageHooks.length + 1]);
+ }
+
+ /**
+ * Adds a bundle file factory to this hook registry.
+ * @param factory an bundle file factory object.
+ */
+ public void addBundleFileFactoryHook(BundleFileFactoryHook factory) {
+ bundleFileFactoryHooks = (BundleFileFactoryHook[]) add(factory, bundleFileFactoryHooks, new BundleFileFactoryHook[bundleFileFactoryHooks.length + 1]);
+ }
+
+ private Object[] add(Object newValue, Object[] oldValues, Object[] newValues) {
+ if (readonly)
+ throw new IllegalStateException("Cannot add hooks dynamically.");
+ if (oldValues.length > 0)
+ System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
+ newValues[oldValues.length] = newValue;
+ return newValues;
+ }
+
+ /**
+ * Returns the base adaptor associated with this hook registry.
+ * @return the base adaptor associated with this hook registry.
+ */
+ public BaseAdaptor getAdaptor() {
+ return adaptor;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleEntry.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleEntry.java
new file mode 100644
index 000000000..b3e8007bc
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleEntry.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.bundlefile;
+
+import java.io.*;
+import java.net.URL;
+
+/**
+ * A BundleEntry represents one entry of a BundleFile.
+ * <p>
+ * Clients may extend this class.
+ * </p>
+ * @since 3.1
+ */
+public abstract class BundleEntry {
+ /**
+ * Return an InputStream for the entry.
+ *
+ * @return InputStream for the entry.
+ * @throws java.io.IOException If an error occurs reading the bundle.
+ */
+ public abstract InputStream getInputStream() throws IOException;
+
+ /**
+ * Return the size of the entry (uncompressed).
+ *
+ * @return size of entry.
+ */
+ public abstract long getSize();
+
+ /**
+ * Return the name of the entry.
+ *
+ * @return name of entry.
+ */
+ public abstract String getName();
+
+ /**
+ * Get the modification time for this BundleEntry.
+ * <p>If the modification time has not been set,
+ * this method will return <tt>-1</tt>.
+ *
+ * @return last modification time.
+ */
+ public abstract long getTime();
+
+ /**
+ * Get a URL to the bundle entry that uses a common protocol (i.e. file:
+ * jar: or http: etc.).
+ * @return a URL to the bundle entry that uses a common protocol
+ */
+ public abstract URL getLocalURL();
+
+ /**
+ * Get a URL to the content of the bundle entry that uses the file: protocol.
+ * The content of the bundle entry may be downloaded or extracted to the local
+ * file system in order to create a file: URL.
+ * @return a URL to the content of the bundle entry that uses the file: protocol
+ */
+ public abstract URL getFileURL();
+
+ /**
+ * Return the name of this BundleEntry by calling getName().
+ *
+ * @return String representation of this BundleEntry.
+ */
+ public String toString() {
+ return (getName());
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleFile.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleFile.java
new file mode 100644
index 000000000..cb07047e8
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleFile.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.bundlefile;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
+import org.eclipse.osgi.framework.internal.protocol.bundleresource.Handler;
+import org.eclipse.osgi.framework.util.SecureAction;
+import org.eclipse.osgi.util.ManifestElement;
+
+/**
+ * The BundleFile API is used by Adaptors to read resources out of an
+ * installed Bundle in the Framework.
+ * <p>
+ * Clients may extend this class.
+ * </p>
+ * @since 3.1
+ */
+abstract public class BundleFile {
+ protected static final String PROP_SETPERMS_CMD = "osgi.filepermissions.command"; //$NON-NLS-1$
+ static final SecureAction secureAction = new SecureAction();
+ /**
+ * The File object for this BundleFile.
+ */
+ protected File basefile;
+ private int mruIndex = -1;
+
+ /**
+ * Default constructor
+ *
+ */
+ public BundleFile() {
+ // do nothing
+ }
+
+ /**
+ * BundleFile constructor
+ * @param basefile The File object where this BundleFile is
+ * persistently stored.
+ */
+ public BundleFile(File basefile) {
+ this.basefile = basefile;
+ }
+
+ /**
+ * Returns a File for the bundle entry specified by the path.
+ * If required the content of the bundle entry is extracted into a file
+ * on the file system.
+ * @param path The path to the entry to locate a File for.
+ * @param nativeCode true if the path is native code.
+ * @return A File object to access the contents of the bundle entry.
+ */
+ abstract public File getFile(String path, boolean nativeCode);
+
+ /**
+ * Locates a file name in this bundle and returns a BundleEntry object
+ *
+ * @param path path of the entry to locate in the bundle
+ * @return BundleEntry object or null if the file name
+ * does not exist in the bundle
+ */
+ abstract public BundleEntry getEntry(String path);
+
+ /**
+ * Allows to access the entries of the bundle.
+ * Since the bundle content is usually a jar, this
+ * allows to access the jar contents.
+ *
+ * GetEntryPaths allows to enumerate the content of "path".
+ * If path is a directory, it is equivalent to listing the directory
+ * contents. The returned names are either files or directories
+ * themselves. If a returned name is a directory, it finishes with a
+ * slash. If a returned name is a file, it does not finish with a slash.
+ * @param path path of the entry to locate in the bundle
+ * @return an Enumeration of Strings that indicate the paths found or
+ * null if the path does not exist.
+ */
+ abstract public Enumeration getEntryPaths(String path);
+
+ /**
+ * Closes the BundleFile.
+ * @throws IOException if any error occurs.
+ */
+ abstract public void close() throws IOException;
+
+ /**
+ * Opens the BundleFiles.
+ * @throws IOException if any error occurs.
+ */
+ abstract public void open() throws IOException;
+
+ /**
+ * Determines if any BundleEntries exist in the given directory path.
+ * @param dir The directory path to check existence of.
+ * @return true if the BundleFile contains entries under the given directory path;
+ * false otherwise.
+ */
+ abstract public boolean containsDir(String dir);
+
+ /**
+ * Returns a URL to access the contents of the entry specified by the path
+ * @param path the path to the resource
+ * @param hostBundleID the host bundle ID
+ * @return a URL to access the contents of the entry specified by the path
+ */
+ public URL getResourceURL(String path, long hostBundleID) {
+ return getResourceURL(path, hostBundleID, 0);
+ }
+
+ /**
+ * Returns a URL to access the contents of the entry specified by the path
+ * @param path the path to the resource
+ * @param hostBundleID the host bundle ID
+ * @param index the resource index
+ * @return a URL to access the contents of the entry specified by the path
+ */
+ public URL getResourceURL(String path, long hostBundleID, int index) {
+ BundleEntry bundleEntry = getEntry(path);
+ if (bundleEntry == null)
+ return null;
+ if (path.length() == 0 || path.charAt(0) != '/')
+ path = '/' + path;
+ try {
+ //use the constant string for the protocol to prevent duplication
+ return secureAction.getURL(Constants.OSGI_RESOURCE_URL_PROTOCOL, Long.toString(hostBundleID), index, path, new Handler(bundleEntry));
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the base file for this BundleFile
+ * @return the base file for this BundleFile
+ */
+ public File getBaseFile() {
+ return basefile;
+ }
+
+ void setMruIndex(int index) {
+ mruIndex = index;
+ }
+
+ int getMruIndex() {
+ return mruIndex;
+ }
+
+ protected static void setPermissions(File nested) {
+ String commandProp = FrameworkProperties.getProperty(PROP_SETPERMS_CMD);
+ if (commandProp == null)
+ return;
+ String[] temp = ManifestElement.getArrayFromList(commandProp, " "); //$NON-NLS-1$
+ ArrayList command = new ArrayList(temp.length + 1);
+ boolean foundFullPath = false;
+ for (int i = 0; i < temp.length; i++) {
+ if ("[fullpath]".equals(temp[i])) { //$NON-NLS-1$
+ command.add(nested.getAbsolutePath());
+ foundFullPath = true;
+ }
+ else
+ command.add(temp[i]);
+ }
+ if (!foundFullPath)
+ command.add(nested.getAbsolutePath());
+ try {
+ Runtime.getRuntime().exec((String[]) command.toArray(new String[command.size()])).waitFor();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirBundleFile.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirBundleFile.java
new file mode 100644
index 000000000..299311528
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirBundleFile.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.bundlefile;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+import org.eclipse.osgi.internal.baseadaptor.AdaptorMsg;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * A BundleFile that uses a directory as its base file.
+ */
+public class DirBundleFile extends BundleFile {
+
+ /**
+ * Constructs a DirBundleFile
+ * @param basefile the base file
+ * @throws IOException
+ */
+ public DirBundleFile(File basefile) throws IOException {
+ super(basefile);
+ if (!BundleFile.secureAction.exists(basefile) || !BundleFile.secureAction.isDirectory(basefile)) {
+ throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_EXCEPTION, basefile));
+ }
+ }
+
+ public File getFile(String path, boolean nativeCode) {
+ File filePath = new File(this.basefile, path);
+ if (BundleFile.secureAction.exists(filePath)) {
+ return filePath;
+ }
+ return null;
+ }
+
+ public BundleEntry getEntry(String path) {
+ File filePath = new File(this.basefile, path);
+ if (!BundleFile.secureAction.exists(filePath)) {
+ return null;
+ }
+ return new FileBundleEntry(filePath, path);
+ }
+
+ public boolean containsDir(String dir) {
+ File dirPath = new File(this.basefile, dir);
+ return BundleFile.secureAction.exists(dirPath) && BundleFile.secureAction.isDirectory(dirPath);
+ }
+
+ public Enumeration getEntryPaths(final String path) {
+ final java.io.File pathFile = new java.io.File(basefile, path);
+ if (!BundleFile.secureAction.exists(pathFile))
+ return null;
+ if (BundleFile.secureAction.isDirectory(pathFile)) {
+ final String[] fileList = BundleFile.secureAction.list(pathFile);
+ if (fileList == null || fileList.length == 0)
+ return null;
+ final String dirPath = path.length() == 0 || path.charAt(path.length() - 1) == '/' ? path : path + '/';
+ return new Enumeration() {
+ int cur = 0;
+
+ public boolean hasMoreElements() {
+ return fileList != null && cur < fileList.length;
+ }
+
+ public Object nextElement() {
+ if (!hasMoreElements()) {
+ throw new NoSuchElementException();
+ }
+ java.io.File childFile = new java.io.File(pathFile, fileList[cur]);
+ StringBuffer sb = new StringBuffer(dirPath).append(fileList[cur++]);
+ if (BundleFile.secureAction.isDirectory(childFile)) {
+ sb.append("/"); //$NON-NLS-1$
+ }
+ return sb.toString();
+ }
+
+ };
+ }
+ return new Enumeration() {
+ int cur = 0;
+
+ public boolean hasMoreElements() {
+ return cur < 1;
+ }
+
+ public Object nextElement() {
+ if (cur == 0) {
+ cur = 1;
+ return path;
+ }
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ public void close() {
+ // nothing to do.
+ }
+
+ public void open() {
+ // nothing to do.
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirZipBundleEntry.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirZipBundleEntry.java
new file mode 100644
index 000000000..ce5be0c78
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/DirZipBundleEntry.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.bundlefile;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * Represents a directory entry in a ZipBundleFile. This object is used to
+ * reference a directory entry in a ZipBundleFile when the directory entries are
+ * not included in the zip file.
+ */
+public class DirZipBundleEntry extends BundleEntry {
+
+ /**
+ * ZipBundleFile for this entry.
+ */
+ private ZipBundleFile bundleFile;
+ /**
+ * The name for this entry
+ */
+ String name;
+
+ public DirZipBundleEntry(ZipBundleFile bundleFile, String name) {
+ this.name = (name.length() > 0 && name.charAt(0) == '/') ? name.substring(1) : name;
+ this.bundleFile = bundleFile;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return null;
+ }
+
+ public long getSize() {
+ return 0;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public long getTime() {
+ return 0;
+ }
+
+ public URL getLocalURL() {
+ try {
+ return new URL("jar:file:" + bundleFile.basefile.getAbsolutePath() + "!/" + name); //$NON-NLS-1$ //$NON-NLS-2$
+ } catch (MalformedURLException e) {
+ //This can not happen, unless the jar protocol is not supported.
+ return null;
+ }
+ }
+
+ public URL getFileURL() {
+ try {
+ return bundleFile.extractDirectory(name).toURL();
+ } catch (MalformedURLException e) {
+ // this cannot happen.
+ return null;
+ }
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/FileBundleEntry.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/FileBundleEntry.java
new file mode 100644
index 000000000..4c75e4a39
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/FileBundleEntry.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.bundlefile;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * A BundleEntry represented by a File object. The FileBundleEntry class is
+ * used for bundles that are installed as extracted zips on a file system.
+ */
+public class FileBundleEntry extends BundleEntry {
+ /**
+ * File for this entry.
+ */
+ private File file;
+ /**
+ * The name for this entry
+ */
+ String name;
+
+ /**
+ * Constructs the BundleEntry using a File.
+ * @param file BundleFile object this entry is a member of
+ * @param name the name of this BundleEntry
+ */
+ FileBundleEntry(File file, String name) {
+ this.file = file;
+ this.name = name;
+ }
+
+ /**
+ * Return an InputStream for the entry.
+ *
+ * @return InputStream for the entry
+ * @exception java.io.IOException
+ */
+ public InputStream getInputStream() throws IOException {
+ return BundleFile.secureAction.getFileInputStream(file);
+ }
+
+ /**
+ * Return size of the uncompressed entry.
+ *
+ * @return size of entry
+ */
+ public long getSize() {
+ return BundleFile.secureAction.length(file);
+ }
+
+ /**
+ * Return name of the entry.
+ *
+ * @return name of entry
+ */
+ public String getName() {
+ return (name);
+ }
+
+ /**
+ * Get the modification time for this BundleEntry.
+ * <p>If the modification time has not been set,
+ * this method will return <tt>-1</tt>.
+ *
+ * @return last modification time.
+ */
+ public long getTime() {
+ return BundleFile.secureAction.lastModified(file);
+ }
+
+ public URL getLocalURL() {
+ return getFileURL();
+ }
+
+ public URL getFileURL() {
+ try {
+ return file.toURL();
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/MRUBundleFileList.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/MRUBundleFileList.java
new file mode 100644
index 000000000..1db8eea0c
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/MRUBundleFileList.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.bundlefile;
+
+import java.io.IOException;
+
+/**
+ * A simple/quick/small implementation of an MRU (Most Recently Used) list to keep
+ * track of open BundleFiles. The MRU will use the file limit specified by the property
+ * &quot;osgi.bundlefile.limit&quot; by default unless the MRU is constructed with a specific
+ * file limit.
+ */
+public class MRUBundleFileList {
+ private static final String PROP_FILE_LIMIT = "osgi.bundlefile.limit"; //$NON-NLS-1$
+ private static final int MIN = 10;
+ // list of open bundle files
+ private BundleFile[] bundleFileList;
+ // list of open bundle files use stamps
+ private long[] useStampList;
+ // the current use stamp
+ private long curUseStamp = 0;
+ // the limit of open files to allow before least used bundle file is closed
+ private int fileLimit = 0; // value < MIN will disable MRU
+ // the current number of open bundle files
+ private int numOpen = 0;
+
+ public MRUBundleFileList() {
+ try {
+ String prop = BundleFile.secureAction.getProperty(PROP_FILE_LIMIT);
+ if (prop != null)
+ init(Integer.parseInt(prop));
+ } catch (NumberFormatException e) {
+ //MRU will be disabled
+ }
+ }
+
+ public MRUBundleFileList(int fileLimit) {
+ init(fileLimit);
+ }
+
+ private void init(int initFileLimit) {
+ // only enable the MRU if the initFileLimit is > MIN
+ if (initFileLimit >= MIN) {
+ this.fileLimit = initFileLimit;
+ this.bundleFileList = new BundleFile[initFileLimit];
+ this.useStampList = new long[initFileLimit];
+ }
+ }
+
+ /**
+ * Adds a BundleFile which is about to be opened to the MRU list. If
+ * the number of open BundleFiles == the fileLimit then the least
+ * recently used BundleFile is closed.
+ * @param bundleFile the bundle file about to be opened.
+ * @throws IOException if an error occurs while closing the least recently used BundleFile
+ */
+ public void add(BundleFile bundleFile) throws IOException {
+ if (fileLimit < MIN)
+ return; // MRU is disabled
+ synchronized (bundleFileList) {
+ int index = 0; // default to the first slot
+ if (numOpen < fileLimit) {
+ // numOpen does not exceed the fileLimit
+ // find the first null slot to use in the MRU
+ for (int i = 0; i < fileLimit; i++)
+ if (bundleFileList[i] == null) {
+ index = i;
+ break;
+ }
+ } else {
+ // numOpen has reached the fileLimit
+ // find the least recently used bundleFile and close it
+ // and use it slot for the new bundleFile to be opened.
+ index = 0;
+ for (int i = 1; i < fileLimit; i++)
+ if (useStampList[i] < useStampList[index])
+ index = i;
+ BundleFile toRemove = bundleFileList[index];
+ remove(toRemove);
+ toRemove.close();
+ }
+ // found an index to place to bundleFile to be opened
+ bundleFileList[index] = bundleFile;
+ bundleFile.setMruIndex(index);
+ incUseStamp(index);
+ numOpen++;
+ }
+ }
+
+ /**
+ * Removes a bundle file which is about to be closed
+ * @param bundleFile the bundle file about to be closed
+ * @return true if the bundleFile existed in the MRU; false otherwise
+ */
+ public boolean remove(BundleFile bundleFile) {
+ if (fileLimit < MIN)
+ return false; // MRU is disabled
+ synchronized (bundleFileList) {
+ int index = bundleFile.getMruIndex();
+ if ((index >= 0 || index < fileLimit) && bundleFileList[index] == bundleFile) {
+ bundleFileList[index] = null;
+ useStampList[index] = -1;
+ numOpen--;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Increments the use stamp of a bundle file
+ * @param bundleFile the bundle file to increment the use stamp for
+ */
+ public void use(BundleFile bundleFile) {
+ if (fileLimit < MIN)
+ return; // MRU is disabled
+ synchronized (bundleFileList) {
+ int index = bundleFile.getMruIndex();
+ if ((index >= 0 || index < fileLimit) && bundleFileList[index] == bundleFile)
+ incUseStamp(index);
+ }
+ }
+
+ private void incUseStamp(int index) {
+ if (curUseStamp == Long.MAX_VALUE) {
+ // we hit the curUseStamp max better reset all the stamps
+ for (int i = 0; i < fileLimit; i++)
+ useStampList[i] = 0;
+ curUseStamp = 0;
+ }
+ useStampList[index] = ++curUseStamp;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/NestedDirBundleFile.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/NestedDirBundleFile.java
new file mode 100644
index 000000000..6946b6803
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/NestedDirBundleFile.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.bundlefile;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+
+/**
+ * A NestedDirBundleFile uses another BundleFile as its source but
+ * accesses all of its resources relative to a nested directory within
+ * the other BundleFile object. This is used to support zipped bundles
+ * that use a Bundle-ClassPath with an nested directory specified.
+ * <p>
+ * For Example:
+ * <pre>
+ * Bundle-ClassPath: nested.jar,nesteddir/
+ * </pre>
+ */
+public class NestedDirBundleFile extends BundleFile {
+ BundleFile baseBundleFile;
+ String cp;
+
+ /**
+ * Constructs a NestedDirBundleFile
+ * @param baseBundlefile the base bundle file
+ * @param cp
+ */
+ public NestedDirBundleFile(BundleFile baseBundlefile, String cp) {
+ super(baseBundlefile.basefile);
+ this.baseBundleFile = baseBundlefile;
+ this.cp = cp;
+ if (cp.charAt(cp.length() - 1) != '/') {
+ this.cp = this.cp + '/';
+ }
+ }
+
+ public void close() {
+ // do nothing.
+ }
+
+ public BundleEntry getEntry(String path) {
+ if (path.length() > 0 && path.charAt(0) == '/')
+ path = path.substring(1);
+ String newpath = new StringBuffer(cp).append(path).toString();
+ return baseBundleFile.getEntry(newpath);
+ }
+
+ public boolean containsDir(String dir) {
+ if (dir == null)
+ return false;
+
+ if (dir.length() > 0 && dir.charAt(0) == '/')
+ dir = dir.substring(1);
+ String newdir = new StringBuffer(cp).append(dir).toString();
+ return baseBundleFile.containsDir(newdir);
+ }
+
+ public Enumeration getEntryPaths(String path) {
+ // getEntryPaths is only valid if this is a root bundle file.
+ return null;
+ }
+
+ public File getFile(String entry, boolean nativeCode) {
+ // getFile is only valid if this is a root bundle file.
+ return null;
+ }
+
+ public void open() throws IOException {
+ // do nothing
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/ZipBundleEntry.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/ZipBundleEntry.java
new file mode 100644
index 000000000..54de51579
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/ZipBundleEntry.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.baseadaptor.bundlefile;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.zip.ZipEntry;
+
+/**
+ * A BundleEntry represented by a ZipEntry in a ZipFile. The ZipBundleEntry
+ * class is used for bundles that are installed as a ZipFile on a file system.
+ */
+public class ZipBundleEntry extends BundleEntry {
+ /**
+ * ZipEntry for this entry.
+ */
+ protected ZipEntry zipEntry;
+
+ /**
+ * The BundleFile for this entry.
+ */
+ protected BundleFile bundleFile;
+
+ /**
+ * Constructs the BundleEntry using a ZipEntry.
+ * @param bundleFile BundleFile object this entry is a member of
+ * @param zipEntry ZipEntry object of this entry
+ */
+ ZipBundleEntry(ZipEntry zipEntry, BundleFile bundleFile) {
+ this.zipEntry = zipEntry;
+ this.bundleFile = bundleFile;
+ }
+
+ /**
+ * Return an InputStream for the entry.
+ *
+ * @return InputStream for the entry
+ * @exception java.io.IOException
+ */
+ public InputStream getInputStream() throws IOException {
+ return ((ZipBundleFile) bundleFile).getZipFile().getInputStream(zipEntry);
+ }
+
+ /**
+ * Return size of the uncompressed entry.
+ *
+ * @return size of entry
+ */
+ public long getSize() {
+ return zipEntry.getSize();
+ }
+
+ /**
+ * Return name of the entry.
+ *
+ * @return name of entry
+ */
+ public String getName() {
+ return zipEntry.getName();
+ }
+
+ /**
+ * Get the modification time for this BundleEntry.
+ * <p>If the modification time has not been set,
+ * this method will return <tt>-1</tt>.
+ *
+ * @return last modification time.
+ */
+ public long getTime() {
+ return zipEntry.getTime();
+ }
+
+ public URL getLocalURL() {
+ try {
+ return new URL("jar:file:" + bundleFile.basefile.getAbsolutePath() + "!/" + zipEntry.getName()); //$NON-NLS-1$//$NON-NLS-2$
+ } catch (MalformedURLException e) {
+ //This can not happen.
+ return null;
+ }
+ }
+
+ public URL getFileURL() {
+ try {
+ File file = bundleFile.getFile(zipEntry.getName(), false);
+ if (file != null)
+ return file.toURL();
+ } catch (MalformedURLException e) {
+ //This can not happen.
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/ZipBundleFile.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/ZipBundleFile.java
new file mode 100644
index 000000000..a13f89b3a
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/ZipBundleFile.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.bundlefile;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.internal.baseadaptor.AdaptorMsg;
+import org.eclipse.osgi.internal.baseadaptor.AdaptorUtil;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.FrameworkEvent;
+
+/**
+ * A BundleFile that uses a ZipFile as it base file.
+ */
+public class ZipBundleFile extends BundleFile {
+ protected static MRUBundleFileList mruList = new MRUBundleFileList();
+
+ /**
+ * The bundle data
+ */
+ protected BaseData bundledata;
+ /**
+ * The zip file
+ */
+ protected ZipFile zipFile;
+ /**
+ * The closed flag
+ */
+ protected boolean closed = true;
+
+ /**
+ * Constructs a ZipBundle File
+ * @param basefile the base file
+ * @param bundledata the bundle data
+ * @throws IOException
+ */
+ public ZipBundleFile(File basefile, BaseData bundledata) throws IOException {
+ super(basefile);
+ if (!BundleFile.secureAction.exists(basefile))
+ throw new IOException(NLS.bind(AdaptorMsg.ADAPTER_FILEEXIST_EXCEPTION, basefile));
+ this.bundledata = bundledata;
+ this.closed = true;
+ }
+
+ /**
+ * Checks if the zip file is open
+ * @return true if the zip file is open
+ */
+ protected boolean checkedOpen() {
+ try {
+ return getZipFile() != null;
+ } catch (IOException e) {
+
+ bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e);
+ return false;
+ }
+ }
+
+ /**
+ * Opens the ZipFile for this bundle file
+ * @return an open ZipFile for this bundle file
+ * @throws IOException
+ */
+ protected ZipFile basicOpen() throws IOException {
+ return BundleFile.secureAction.getZipFile(this.basefile);
+ }
+
+ /**
+ * Returns an open ZipFile for this bundle file. If an open
+ * ZipFile does not exist then a new one is created and
+ * returned.
+ * @return an open ZipFile for this bundle
+ * @throws IOException
+ */
+ protected ZipFile getZipFile() throws IOException {
+ if (closed) {
+ mruList.add(this);
+ zipFile = basicOpen();
+ closed = false;
+ } else
+ mruList.use(this);
+ return zipFile;
+ }
+
+ protected ZipEntry getZipEntry(String path) {
+ if (path.length() > 0 && path.charAt(0) == '/')
+ path = path.substring(1);
+ ZipEntry entry = zipFile.getEntry(path);
+ if (entry != null && entry.getSize() == 0 && !entry.isDirectory()) {
+ // work around the directory bug see bug 83542
+ ZipEntry dirEntry = zipFile.getEntry(path + '/');
+ if (dirEntry != null)
+ entry = dirEntry;
+ }
+ return entry;
+ }
+
+ /**
+ * Extracts a directory and all sub content to disk
+ * @param dirName the directory name to extract
+ * @return the File used to extract the content to. A value
+ * of <code>null</code> is returned if the directory to extract does
+ * not exist or if content extraction is not supported.
+ */
+ protected File extractDirectory(String dirName) {
+ if (!checkedOpen())
+ return null;
+ Enumeration entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ String entryPath = ((ZipEntry) entries.nextElement()).getName();
+ if (entryPath.startsWith(dirName) && !entryPath.endsWith("/")) //$NON-NLS-1$
+ getFile(entryPath, false);
+ }
+ return getExtractFile(dirName);
+ }
+
+ protected File getExtractFile(String entryName) {
+ String path = ".cp"; /* put all these entries in this subdir *///$NON-NLS-1$
+ String name = entryName.replace('/', File.separatorChar);
+ if ((name.length() > 1) && (name.charAt(0) == File.separatorChar)) /* if name has a leading slash */
+ path = path.concat(name);
+ else
+ path = path + File.separator + name;
+ return bundledata.getExtractFile(path);
+ }
+
+ public File getFile(String entry, boolean nativeCode) {
+ if (!checkedOpen())
+ return null;
+ ZipEntry zipEntry = getZipEntry(entry);
+ if (zipEntry == null)
+ return null;
+
+ try {
+ File nested = getExtractFile(zipEntry.getName());
+ if (nested != null) {
+ if (nested.exists()) {
+ /* the entry is already cached */
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("File already present: " + nested.getPath()); //$NON-NLS-1$
+ } else {
+ if (zipEntry.getName().endsWith("/")) { //$NON-NLS-1$
+ if (!nested.mkdirs()) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("Unable to create directory: " + nested.getPath()); //$NON-NLS-1$
+ throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, nested.getAbsolutePath()));
+ }
+ extractDirectory(zipEntry.getName());
+ } else {
+ InputStream in = zipFile.getInputStream(zipEntry);
+ if (in == null)
+ return null;
+ /* the entry has not been cached */
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("Creating file: " + nested.getPath()); //$NON-NLS-1$
+ /* create the necessary directories */
+ File dir = new File(nested.getParent());
+ if (!dir.exists() && !dir.mkdirs()) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("Unable to create directory: " + dir.getPath()); //$NON-NLS-1$
+ throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, dir.getAbsolutePath()));
+ }
+ /* copy the entry to the cache */
+ AdaptorUtil.readFile(in, nested);
+ if (nativeCode)
+ setPermissions(nested);
+ }
+ }
+
+ return nested;
+ }
+ } catch (IOException e) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.printStackTrace(e);
+ }
+ return null;
+ }
+
+ public boolean containsDir(String dir) {
+ if (!checkedOpen())
+ return false;
+ if (dir == null)
+ return false;
+
+ if (dir.length() == 0)
+ return true;
+
+ if (dir.charAt(0) == '/') {
+ if (dir.length() == 1)
+ return true;
+ dir = dir.substring(1);
+ }
+
+ if (dir.length() > 0 && dir.charAt(dir.length() - 1) != '/')
+ dir = dir + '/';
+
+ Enumeration entries = zipFile.entries();
+ ZipEntry zipEntry;
+ String entryPath;
+ while (entries.hasMoreElements()) {
+ zipEntry = (ZipEntry) entries.nextElement();
+ entryPath = zipEntry.getName();
+ if (entryPath.startsWith(dir)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public BundleEntry getEntry(String path) {
+ if (!checkedOpen())
+ return null;
+ ZipEntry zipEntry = getZipEntry(path);
+ if (zipEntry == null) {
+ if (path.length() == 0 || path.charAt(path.length() - 1) == '/') {
+ // this is a directory request lets see if any entries exist in this directory
+ if (containsDir(path))
+ return new DirZipBundleEntry(this, path);
+ }
+ return null;
+ }
+
+ return new ZipBundleEntry(zipEntry, this);
+
+ }
+
+ public Enumeration getEntryPaths(String path) {
+ if (!checkedOpen())
+ return null;
+ if (path == null)
+ throw new NullPointerException();
+
+ if (path.length() > 0 && path.charAt(0) == '/')
+ path = path.substring(1);
+ if (path.length() > 0 && path.charAt(path.length() - 1) != '/')
+ path = new StringBuffer(path).append("/").toString(); //$NON-NLS-1$
+
+ Vector vEntries = new Vector();
+ Enumeration entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry zipEntry = (ZipEntry) entries.nextElement();
+ String entryPath = zipEntry.getName();
+ if (entryPath.startsWith(path)) {
+ if (path.length() < entryPath.length()) {
+ if (entryPath.lastIndexOf('/') < path.length()) {
+ vEntries.add(entryPath);
+ } else {
+ entryPath = entryPath.substring(path.length());
+ int slash = entryPath.indexOf('/');
+ entryPath = path + entryPath.substring(0, slash + 1);
+ if (!vEntries.contains(entryPath))
+ vEntries.add(entryPath);
+ }
+ }
+ }
+ }
+ return vEntries.size() == 0 ? null : vEntries.elements();
+ }
+
+ public void close() throws IOException {
+ if (!closed) {
+ closed = true;
+ zipFile.close();
+ mruList.remove(this);
+ }
+ }
+
+ public void open() throws IOException {
+ //do nothing
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/AdaptorHook.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/AdaptorHook.java
new file mode 100644
index 000000000..2350ea861
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/AdaptorHook.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.hooks;
+
+import java.io.IOException;
+import java.net.URLConnection;
+import java.util.Properties;
+import org.eclipse.osgi.baseadaptor.BaseAdaptor;
+import org.eclipse.osgi.baseadaptor.HookRegistry;
+import org.eclipse.osgi.framework.adaptor.EventPublisher;
+import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
+import org.eclipse.osgi.framework.log.FrameworkLog;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+
+/**
+ * An AdaptorHook hooks into the <code>BaseAdaptor</code> class.
+ * @see BaseAdaptor
+ * @see HookRegistry#getAdaptorHooks()
+ * @see HookRegistry#addAdaptorHook(AdaptorHook)
+ */
+public interface AdaptorHook {
+ /**
+ * Gets called by the adaptor during {@link FrameworkAdaptor#initialize(EventPublisher)}.
+ * This method allows an adaptor hook to save the adaptor object for later.
+ * @param adaptor the adaptor object associated with this AdaptorHook.
+ */
+ public void initialize(BaseAdaptor adaptor);
+
+ /**
+ * Gets called by the adaptor during {@link FrameworkAdaptor#frameworkStart(BundleContext)}.
+ * This method allows an adaptor hook to execute code when the framework is starting
+ * (e.g. to register services).
+ * @param context the system bundle context
+ * @throws BundleException if an error occurs
+ */
+ public void frameworkStart(BundleContext context) throws BundleException;
+
+ /**
+ * Gets called by the adaptor during {@link FrameworkAdaptor#frameworkStop(BundleContext)}.
+ * This method allows an adaptor hook to execute code when the framework is stopped
+ * (e.g. to unregister services).
+ * @param context the system bundle context
+ * @throws BundleException if an error occurs.
+ */
+ public void frameworkStop(BundleContext context) throws BundleException;
+
+ /**
+ * Gets called by the adaptor during {@link FrameworkAdaptor#frameworkStopping(BundleContext)}.
+ * This method allows an adaptor hook to execute code when the framework is about to start
+ * the shutdown process.
+ * @param context the system bundle context
+ */
+ public void frameworkStopping(BundleContext context);
+
+ /**
+ * Gets called by the adaptor during {@link FrameworkAdaptor#getProperties()}.
+ * This method allows an adaptor hook to add property values to the adaptor
+ * properties object.
+ * @param properties the adaptor properties object.
+ */
+ public void addProperties(Properties properties);
+
+ /**
+ * Gets called by the adaptor during {@link FrameworkAdaptor#mapLocationToURLConnection(String)}.
+ * The adaptor will call this method for each configured adaptor hook until one
+ * adaptor hook returns a non-null value. If no adaptor hook returns a non-null value
+ * then the adaptor will perform the default behavior.
+ * @param location a bundle location string to be converted to a URLConnection
+ * @return the URLConnection converted from the bundle location or null.
+ * @throws IOException if an error occured creating the URLConnection
+ */
+ public URLConnection mapLocationToURLConnection(String location) throws IOException;
+
+ /**
+ * Gets called by the adaptor during {@link FrameworkAdaptor#handleRuntimeError(Throwable)}.
+ * The adaptor will call this method for each configured adaptor hook.
+ * @param error the unexpected error that occured.
+ */
+ public void handleRuntimeError(Throwable error);
+
+ /**
+ * Gets called by the adaptor during {@link FrameworkAdaptor#matchDNChain(String, String[])}.
+ * The adaptor will call this method for each configured adaptor hook until one
+ * adaptor hook returns a true value. If no adaptor hook returns a true value
+ * then the adaptor will return false.
+ * @param pattern A
+ * @param dnChain
+ * @return true if the pattern matches
+ */
+ public boolean matchDNChain(String pattern, String[] dnChain);
+
+ /**
+ * Gets called by the adaptor during {@link FrameworkAdaptor#getFrameworkLog()}.
+ * The adaptor will call this method for each configured adaptor hook until one
+ * adaptor hook returns a non-null value. If no adaptor hook returns a non-null value
+ * then the adaptor will return null.
+ * @return a FrameworkLog object or null.
+ */
+ public FrameworkLog createFrameworkLog();
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/BundleFileFactoryHook.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/BundleFileFactoryHook.java
new file mode 100644
index 000000000..c0452d0fd
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/BundleFileFactoryHook.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.hooks;
+
+import java.io.IOException;
+import org.eclipse.osgi.baseadaptor.BaseAdaptor;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
+
+/**
+ * A factory that creates bundle file objects.
+ * @see BaseAdaptor#createBundleFile(Object, BaseData)
+ */
+public interface BundleFileFactoryHook {
+ /**
+ * Creates a bundle file for the given content and base data.
+ * @param content The object which contains the content of a bundle file.
+ * @param data The base data associated with the content
+ * @param base true if the content is for the base bundle (not an inner jar, directory etc.)
+ * @return a new bundle file for the specified content, or null if this factory cannot
+ * create a bundle file for the specified content.
+ * @throws IOException if an IO error occurs
+ */
+ BundleFile createBundleFile(Object content, BaseData data, boolean base) throws IOException;
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/ClassLoadingHook.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/ClassLoadingHook.java
new file mode 100644
index 000000000..bf4d2b118
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/ClassLoadingHook.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.hooks;
+
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.HookRegistry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.loader.*;
+import org.eclipse.osgi.framework.adaptor.*;
+
+/**
+ * A ClassLoadingHook hooks into the <code>ClasspathManager</code> class.
+ * @see ClasspathManager
+ * @see HookRegistry#getClassLoadingHooks()
+ * @see HookRegistry#addClassLoadingHook(ClassLoadingHook)
+ */
+public interface ClassLoadingHook {
+ /**
+ * Gets called by a classpath manager before defining a class. This method allows a class loading hook
+ * to process the bytes of a class that is about to be defined.
+ * @param name the name of the class being defined
+ * @param classbytes the bytes of the class being defined
+ * @param classpathEntry the ClasspathEntry where the class bytes have been read from.
+ * @param entry the BundleEntry source of the class bytes
+ * @param manager the class path manager used to define the requested class
+ * @return a modified array of classbytes or null if the original bytes should be used.
+ */
+ byte[] processClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager);
+
+ /**
+ * Gets called by a classpath manager when looking for ClasspathEntry objects. This method allows
+ * a classloading hook to add additional ClasspathEntry objects
+ * @param cpEntries the list of ClasspathEntry objects currently available for the requested classpath
+ * @param cp the name of the requested classpath
+ * @param hostmanager the classpath manager the requested ClasspathEntry is for
+ * @param sourcedata the source bundle data of the requested ClasspathEntry
+ * @param sourcedomain the source domain of the requested ClasspathEntry
+ * @return true if a ClasspathEntry has been added to cpEntries
+ */
+ boolean addClassPathEntry(ArrayList cpEntries, String cp, ClasspathManager hostmanager, BaseData sourcedata, ProtectionDomain sourcedomain);
+
+ /**
+ * Gets called by a base data during {@link BundleData#findLibrary(String)}.
+ * A base data will call this method for each configured class loading hook until one
+ * class loading hook returns a non-null value. If no class loading hook returns
+ * a non-null value then the base data will return null.
+ * @param data the base data to find a native library for.
+ * @param libName the name of the native library.
+ * @return The absolute path name of the native library or null.
+ */
+ String findLibrary(BaseData data, String libName);
+
+ /**
+ * Gets called by the adaptor during {@link FrameworkAdaptor#getBundleClassLoaderParent()}.
+ * The adaptor will call this method for each configured class loading hook until one
+ * class loading hook returns a non-null value. If no class loading hook returns
+ * a non-null value then the adaptor will perform the default behavior.
+ * @return the parent classloader to be used by all bundle classloaders or null.
+ */
+ public ClassLoader getBundleClassLoaderParent();
+
+ /**
+ * Gets called by a base data during
+ * {@link BundleData#createClassLoader(ClassLoaderDelegate, BundleProtectionDomain, String[])}.
+ * The BaseData will call this method for each configured class loading hook until one data
+ * hook returns a non-null value. If no class loading hook returns a non-null value then a
+ * default implemenation of BundleClassLoader will be created.
+ * @param parent the parent classloader for the BundleClassLoader
+ * @param delegate the delegate for the bundle classloader
+ * @param domain the domian for the bundle classloader
+ * @param data the BundleData for the BundleClassLoader
+ * @param bundleclasspath the classpath for the bundle classloader
+ * @return a newly created bundle classloader
+ */
+ BaseClassLoader createClassLoader(ClassLoader parent, ClassLoaderDelegate delegate, BundleProtectionDomain domain, BaseData data, String[] bundleclasspath);
+
+ /**
+ * Gets called by a base data during
+ * {@link BundleData#createClassLoader(ClassLoaderDelegate, BundleProtectionDomain, String[])}.
+ * The BaseData will call this method for each configured class loading hook after a
+ * BundleClassLoader has been created.
+ * @param baseClassLoader the newly created bundle classloader
+ * @param data the BundleData associated with the bundle classloader
+ */
+ void initializedClassLoader(BaseClassLoader baseClassLoader, BaseData data);
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/ClassLoadingStatsHook.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/ClassLoadingStatsHook.java
new file mode 100644
index 000000000..8a282a29e
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/ClassLoadingStatsHook.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.hooks;
+
+import java.net.URL;
+import org.eclipse.osgi.baseadaptor.HookRegistry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry;
+import org.eclipse.osgi.baseadaptor.loader.ClasspathManager;
+
+/**
+ * A ClassLoadingStatsHook hooks into the <code>ClasspathManager</code> class. This class allows
+ * a hook to record statistics about classloading.
+ * @see ClasspathManager
+ * @see HookRegistry#getClassLoadingStatsHooks()
+ * @see HookRegistry#addClassLoadingStatsHook(ClassLoadingStatsHook)
+ */
+public interface ClassLoadingStatsHook {
+ /**
+ * Gets called by a classpath manager during {@link ClasspathManager#findLocalClass(String)} before
+ * searching the local classloader for a class. A classpath manager will call this method for
+ * each configured class loading stat hook.
+ * @param name the name of the requested class
+ * @param manager the classpath manager used to find and load the requested class
+ * @throws ClassNotFoundException to prevent the requested class from loading
+ */
+ void preFindLocalClass(String name, ClasspathManager manager) throws ClassNotFoundException;
+
+ /**
+ * Gets called by a classpath manager during {@link ClasspathManager#findLocalClass(String)} after
+ * searching the local classloader for a class. A classpath manager will call this method for
+ * each configured class loading stat hook.
+ * @param name the name of the requested class
+ * @param clazz the loaded class or null if not found
+ * @param manager the classpath manager used to find and load the requested class
+ */
+ void postFindLocalClass(String name, Class clazz, ClasspathManager manager);
+
+ /**
+ * Gets called by a classpath manager during {@link ClasspathManager#findLocalResource(String)} before
+ * searching the local classloader for a resource. A classpath manager will call this method for
+ * each configured class loading stat hook.
+ * @param name the name of the requested resource
+ * @param manager the classpath manager used to find the requested resource
+ */
+ void preFindLocalResource(String name, ClasspathManager manager);
+
+ /**
+ * Gets called by a classpath manager during {@link ClasspathManager#findLocalResource(String)} after
+ * searching the local classloader for a resource. A classpath manager will call this method for
+ * each configured class loading stat hook.
+ * @param name the name of the requested resource
+ * @param resource the URL to the requested resource or null if not found
+ * @param manager the classpath manager used to find the requested resource
+ */
+ void postFindLocalResource(String name, URL resource, ClasspathManager manager);
+
+ /**
+ * Gets called by a classpath manager after a successfully defining a class. This method allows
+ * a class loading stat hook to record data about a class definition.
+ * @param name the name of the class that got defined
+ * @param clazz the class object that got defined
+ * @param classbytes the class bytes used to define the class
+ * @param classpathEntry the ClasspathEntry where the class bytes got read from
+ * @param entry the BundleEntyr source of the class bytes
+ * @param manager the classpath manager used to define the class
+ */
+ void recordClassDefine(String name, Class clazz, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager);
+
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/StorageHook.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/StorageHook.java
new file mode 100644
index 000000000..114ce062d
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/hooks/StorageHook.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.hooks;
+
+import java.io.*;
+import java.util.Dictionary;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.framework.adaptor.BundleData;
+import org.eclipse.osgi.framework.util.KeyedElement;
+import org.osgi.framework.BundleException;
+
+/**
+ * A StorageHook hooks into the persistent storage loading and saving. A StorageHook gets
+ * associated with each BaseData object installed in the adaptor.<p>
+ * A StorageHook extends {@link KeyedElement}, the key used for the element must be the
+ * fully qualified string name of the StorageHook implementation class.
+ * @see BaseData#getStorageHook(String)
+ */
+public interface StorageHook extends KeyedElement {
+ /**
+ * Returns the storage version of this storage hook. This version
+ * is used by the storage to check the consistency of cached persistent
+ * data. Any time a storage hook changes the format of its persistent
+ * data the storage version should be incremented.
+ * @return the storage version of this storage hook
+ */
+ int getStorageVersion();
+
+ /**
+ * Creates an uninitialized storage hook for the specified bundledata. This method
+ * is called when a bundle is installed or updated. The returned storage hook will be
+ * used for the new contents of the bundle. The returned hook will have its
+ * {@link #initialize(Dictionary)} method called to initialize the storage hook.
+ * @param bundledata a base data the created storage hook will be associated with
+ * @return an uninitialized storage hook
+ * @throws BundleException if any error occurs
+ */
+ StorageHook create(BaseData bundledata) throws BundleException;
+
+ /**
+ * Initializes this storage hook with the content of the specified bundle manifest.
+ * This method is called when a bundle is installed or updated.
+ * @see #create(BaseData)
+ * @see #copy(StorageHook)
+ * @param manifest the bundle manifest to load into this storage hook
+ * @throws BundleException if any error occurs
+ */
+ void initialize(Dictionary manifest) throws BundleException;
+
+ /**
+ * Creates a new storage hook and loads the data from the specified
+ * input stream into the storage hook. This method is called during startup to
+ * load all the persistently installed bundles. <p>
+ * It is important that this method and the {@link #save(DataOutputStream)} method
+ * stay in sync. This method must be able to successfully read the data saved by the
+ * {@link #save(DataOutputStream)} method.
+ * @param bundledata a base data the loaded storage hook will be associated with
+ * @param is an input stream used to load the storage hook's data from.
+ * @return a loaded storage hook
+ * @see #save(DataOutputStream)
+ * @throws IOException if any error occurs
+ */
+ StorageHook load(BaseData bundledata, DataInputStream is) throws IOException;
+
+ /**
+ * Saves the data from this storage hook into the specified output stream. This method
+ * is called if some persistent data has changed for the bundle. <p>
+ * It is important that this method and the {@link #load(BaseData, DataInputStream)}
+ * method stay in sync. This method must be able to save data which the
+ * {@link #load(BaseData, DataInputStream)} method can ready successfully.
+ * @see #load(BaseData, DataInputStream)
+ * @param os an output stream used to save the storage hook's data from.
+ * @throws IOException if any error occurs
+ */
+ void save(DataOutputStream os) throws IOException;
+
+ /**
+ * Copies the data from the specified storage hook into this storage hook. This method
+ * is called when a bundle is updated to copy the data from the original bundle to a
+ * new storage hook. Then this storage will be initialized with the new bundle's
+ * manifest using the {@link #initialize(Dictionary)} method.
+ * @see #create(BaseData)
+ * @see #initialize(Dictionary)
+ * @param storageHook the original storage hook to copy data out of.
+ */
+ void copy(StorageHook storageHook);
+
+ /**
+ * Validates the data in this storage hook, if the data is invalid then an illegal state
+ * exception is thrown
+ * @throws IllegalArgumentException if the data is invalid
+ */
+ void validate() throws IllegalArgumentException;
+
+ /**
+ * Returns the manifest for the data in this storage hook, or null if this hook does
+ * not provide the manifest. Most hooks should return null from this method. This
+ * method may be used to provide special handling of manifest loading. For example,
+ * to provide a cached manfest or to do automatic manifest generation.
+ * @param firstLoad true if this is the very first time this manifest is being loaded.
+ * @return the manifest for the data in this storage hook, or null if this hook does
+ * not provide the manifest
+ * @throws BundleException
+ */
+ Dictionary getManifest(boolean firstLoad) throws BundleException;
+
+ /**
+ * Gets called by a base data during {@link BundleData#setStatus(int)}.
+ * A base data will call this method for each configured storage hook it
+ * is associated with until one storage hook returns true. If all configured storage
+ * hooks return false then the BaseData will be marked dirty and will cause the
+ * status to be persistently saved.
+ * @param status the new status of the base data
+ * @return false if the status is not to be persistently saved; otherwise true is returned
+ */
+ boolean forgetStatusChange(int status);
+
+ /**
+ * Gets called by a base data during {@link BundleData#setStartLevel(int)}.
+ * A base data will call this method for each configured storage hook it
+ * is associated with until one storage hook returns true. If all configured storage
+ * hooks return false then the BaseData will be marked dirty and will cause the
+ * start level to be persistently saved.
+ * @param startlevel the new startlevel of the base data
+ * @return false if the startlevel is not to be persistently saved; otherwise true is returned
+ */
+ boolean forgetStartLevelChange(int startlevel);
+
+ /**
+ * Gets called by a base data during {@link BundleData#matchDNChain(String)}.
+ * A base data will call this method for each configured storage hook it
+ * is associated with until one storage hook returns true. If all configured storage
+ * hooks return false value then the BaseAdaptor will return false.
+ * @param pattern the pattern of distinguished name (DN) chains to match
+ * @return true if the pattern matches. A value of false is returned
+ * if bundle signing is not supported.
+ */
+ boolean matchDNChain(String pattern);
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/BaseClassLoader.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/BaseClassLoader.java
new file mode 100644
index 000000000..a93dffbbe
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/BaseClassLoader.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.loader;
+
+import java.net.URL;
+import java.security.ProtectionDomain;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
+import org.eclipse.osgi.framework.adaptor.BundleClassLoader;
+
+/**
+ * The actual class loader object used to define classes for a classpath manager.
+ * This interface provides public versions of a few methods on class loader.
+ * @see ClasspathManager
+ */
+public interface BaseClassLoader extends BundleClassLoader {
+ /**
+ * Returns the domain for the host bundle of this class loader
+ * @return the domain for the host bundle of this class loader
+ */
+ ProtectionDomain getDomain();
+
+ /**
+ * Creates a classpath entry with the given bundle file and domain
+ * @param bundlefile the source bundle file for a classpath entry
+ * @param cpDomain the source domain for a classpath entry
+ * @return a classpath entry with the given bundle file and domain
+ */
+ ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain cpDomain);
+
+ /**
+ * Defines a Class.
+ * @param name the name of the class to define
+ * @param classbytes the bytes of the class to define
+ * @param classpathEntry the classpath entry used to load the class bytes
+ * @param entry the bundle entry used to load the class bytes
+ * @return a defined Class
+ */
+ Class defineClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry);
+
+ /**
+ * A public version of the {@link ClassLoader#findLoadedClass(java.lang.String)} method.
+ * @param classname the class name to find.
+ * @return a loaded class
+ */
+ Class publicFindLoaded(String classname);
+
+ /**
+ * A public version of the {@link ClassLoader#getPackage(java.lang.String)} method.
+ * @param pkgname the package name to get.
+ * @return the package or null if it does not exist
+ */
+ Object publicGetPackage(String pkgname);
+
+ /**
+ * A public version of the {@link ClassLoader#definePackage(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.net.URL)} method.
+ * @return a defined Package
+ */
+ Object publicDefinePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase);
+
+ /**
+ * Returns the ClasspathManager for this BaseClassLoader
+ * @return the ClasspathManager
+ */
+ ClasspathManager getClasspathManager();
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathEntry.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathEntry.java
new file mode 100644
index 000000000..3ddbfcd1b
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathEntry.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.loader;
+
+import java.security.ProtectionDomain;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
+import org.eclipse.osgi.framework.util.KeyedElement;
+import org.eclipse.osgi.framework.util.KeyedHashSet;
+
+/**
+ * A ClasspathEntry contains a single <code>BundleFile</code> which is used as
+ * a source to load classes and resources from, and a single
+ * <code>ProtectionDomain</code> which is used as the domain to define classes
+ * loaded from this ClasspathEntry.
+ */
+public class ClasspathEntry {
+ private BundleFile bundlefile;
+ private ProtectionDomain domain;
+ private KeyedHashSet userObjects = null;
+
+ /**
+ * Constructs a ClasspathElement with the specified bundlefile and domain
+ * @param bundlefile A BundleFile object which acts as a source
+ * @param domain the ProtectDomain for all code loaded from this classpath element
+ */
+ public ClasspathEntry(BundleFile bundlefile, ProtectionDomain domain) {
+ this.bundlefile = bundlefile;
+ this.domain = domain;
+ }
+
+ /**
+ * Returns the source BundleFile for this classpath entry
+ * @return the source BundleFile for this classpath entry
+ */
+ public BundleFile getBundleFile() {
+ return bundlefile;
+ }
+
+ /**
+ * Returns the ProtectionDomain for this classpath entry
+ * @return the ProtectionDomain for this classpath entry
+ */
+ public ProtectionDomain getDomain() {
+ return domain;
+ }
+
+ /**
+ * Returns a user object which is keyed by the specified key
+ * @param key the key of the user object to get
+ * @return a user object which is keyed by the specified key
+ */
+ public Object getUserObject(Object key) {
+ if (userObjects == null)
+ return null;
+ synchronized (userObjects) {
+ return userObjects.getByKey(key);
+ }
+ }
+
+ /**
+ * Adds a user object
+ * @param userObject the user object to add
+ */
+ public synchronized void addUserObject(KeyedElement userObject) {
+ if (userObjects == null)
+ userObjects = new KeyedHashSet(5, false);
+ synchronized (userObjects) {
+ userObjects.add(userObject);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathManager.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathManager.java
new file mode 100644
index 000000000..7291e8e7c
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathManager.java
@@ -0,0 +1,572 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.loader;
+
+import java.io.*;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.*;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.bundlefile.*;
+import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook;
+import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingStatsHook;
+import org.eclipse.osgi.framework.adaptor.BundleData;
+import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.internal.baseadaptor.AdaptorMsg;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkEvent;
+
+/**
+ * A helper class for <code>BaseClassLoader</code> implementations. This class will keep track of
+ * <code>ClasspathEntry</code> objects for the host bundle and any attached fragment bundles. This
+ * class takes care of seaching the <code>ClasspathEntry</code> objects for a base class loader
+ * implementation. Additional behavior may be added to a classpath manager by configuring
+ * <code>ClassLoadingHook</code> and <code>ClassLoadingStatsHook</code>.
+ * @see BaseClassLoader
+ * @see ClassLoadingHook
+ * @see ClassLoadingStatsHook
+ */
+public class ClasspathManager {
+ private static final FragmentClasspath[] emptyFragments = new FragmentClasspath[0];
+ private static final int BUF_SIZE = 8 * 1024;
+
+ private BaseData data;
+ private String[] classpath;
+ private ClasspathEntry[] entries;
+ private BaseClassLoader classloader;
+ private FragmentClasspath[] fragments = emptyFragments;
+
+ /**
+ * Constructs a classpath manager for the given host base data, classpath and base class loader
+ * @param data the host base data for this classpath manager
+ * @param classpath the host classpath for this classpath manager
+ * @param classloader the BaseClassLoader for this classpath manager
+ */
+ public ClasspathManager(BaseData data, String[] classpath, BaseClassLoader classloader) {
+ this.data = data;
+ this.classpath = classpath;
+ this.classloader = classloader;
+ }
+
+ /**
+ * initializes this classpath manager. This must be called after all existing fragments have been
+ * attached and before any resources/classes are loaded using this classpath manager.
+ */
+ public void initialize() {
+ entries = buildClasspath(classpath, this, data, classloader.getDomain());
+ }
+
+ /**
+ * Closes all the classpath entry resources for this classpath manager.
+ *
+ */
+ public void close() {
+ if (entries != null) {
+ for (int i = 0; i < entries.length; i++) {
+ if (entries[i] != null) {
+ try {
+ entries[i].getBundleFile().close();
+ } catch (IOException e) {
+ data.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, data.getBundle(), e);
+ }
+ }
+ }
+ }
+ for (int i = 0; i < fragments.length; i++)
+ fragments[i].close();
+ }
+
+ /**
+ * Attaches the specified sourcedata, sourcedomain and sourceclasspath to this classpath manager
+ * @param sourcedata the source fragment BundleData that should be attached.
+ * @param sourcedomain the source fragment domain that should be attached.
+ * @param sourceclasspath the source fragment classpath that should be attached.
+ */
+ public void attachFragment(BundleData sourcedata, ProtectionDomain sourcedomain, String[] sourceclasspath) {
+ try {
+ sourcedata.open(); /* make sure the BundleData is open */
+ } catch (IOException e) {
+ ((BaseData) sourcedata).getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, ((BaseData) sourcedata).getBundle(), e);
+ }
+ ClasspathEntry[] fragEntries = buildClasspath(sourceclasspath, this, (BaseData) sourcedata, sourcedomain);
+ FragmentClasspath fragClasspath = new FragmentClasspath((BaseData) sourcedata, fragEntries, sourcedomain);
+ insertFragment(fragClasspath);
+ }
+
+ private synchronized void insertFragment(FragmentClasspath fragClasspath) {
+ FragmentClasspath[] newFragments = new FragmentClasspath[fragments.length + 1];
+ // Find a place in the fragment list to insert this fragment.
+ long fragID = fragClasspath.getBundleData().getBundleID();
+ int insert = 0;
+ for (int i = 0; i < fragments.length; i++) {
+ long otherID = fragments[i].getBundleData().getBundleID();
+ if (insert == 0 && fragID < otherID) {
+ newFragments[i] = fragClasspath;
+ insert = 1;
+ }
+ newFragments[i + insert] = fragments[i];
+ }
+ // This fragment has the highest ID; put it at the end of the list.
+ if (insert == 0)
+ newFragments[fragments.length] = fragClasspath;
+ fragments = newFragments;
+ }
+
+ private static ClasspathEntry[] buildClasspath(String[] cp, ClasspathManager hostloader, BaseData sourcedata, ProtectionDomain sourcedomain) {
+ ArrayList result = new ArrayList(cp.length);
+ // add the regular classpath entries.
+ for (int i = 0; i < cp.length; i++)
+ findClassPathEntry(result, cp[i], hostloader, sourcedata, sourcedomain);
+ return (ClasspathEntry[]) result.toArray(new ClasspathEntry[result.size()]);
+ }
+
+ /**
+ * Finds all the ClasspathEntry objects for the requested classpath. This method will first call all
+ * the configured class loading hooks {@link ClassLoadingHook#addClassPathEntry(ArrayList, String, ClasspathManager, BaseData, ProtectionDomain)}
+ * methods. This allows class loading hooks to add additional ClasspathEntry objects to the result for the
+ * requested classpath. Then the local host classpath entries and attached fragment classpath entries are
+ * searched.
+ * @param result a list of ClasspathEntry objects. This list is used to add new ClasspathEntry objects to.
+ * @param cp the requested classpath.
+ * @param hostloader the host classpath manager for the classpath
+ * @param sourcedata the source EquionoxData to search for the classpath
+ * @param sourcedomain the source domain to used by the new ClasspathEntry
+ */
+ public static void findClassPathEntry(ArrayList result, String cp, ClasspathManager hostloader, BaseData sourcedata, ProtectionDomain sourcedomain) {
+ // look in classpath manager hooks first
+ ClassLoadingHook[] loaderHooks = sourcedata.getAdaptor().getHookRegistry().getClassLoadingHooks();
+ boolean hookAdded = false;
+ for (int i = 0; i < loaderHooks.length; i++)
+ hookAdded |= loaderHooks[i].addClassPathEntry(result, cp, hostloader, sourcedata, sourcedomain);
+ if (!addClassPathEntry(result, cp, hostloader, sourcedata, sourcedomain) && !hookAdded) {
+ BundleException be = new BundleException(NLS.bind(AdaptorMsg.BUNDLE_CLASSPATH_ENTRY_NOT_FOUND_EXCEPTION, cp, sourcedata.getLocation()));
+ sourcedata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.INFO, sourcedata.getBundle(), be);
+ }
+ }
+
+ /**
+ * Adds a ClasspathEntry for the requested classpath to the result. The local host classpath entries
+ * are searched first and then attached fragments classpath entries are searched. The search stops once the first
+ * classpath entry is found.
+ * @param result a list of ClasspathEntry objects. This list is used to add new ClasspathEntry objects to.
+ * @param cp the requested classpath.
+ * @param hostloader the host classpath manager for the classpath
+ * @param sourcedata the source EquionoxData to search for the classpath
+ * @param sourcedomain the source domain to used by the new ClasspathEntry
+ * @return true if a ClasspathEntry was added to the result
+ */
+ public static boolean addClassPathEntry(ArrayList result, String cp, ClasspathManager hostloader, BaseData sourcedata, ProtectionDomain sourcedomain) {
+ if (cp.equals(".")) { //$NON-NLS-1$
+ result.add(hostloader.createClassPathEntry(sourcedata.getBundleFile(), sourcedomain));
+ return true;
+ }
+ Object element = hostloader.getClasspath(cp, sourcedata, sourcedomain);
+ if (element != null) {
+ result.add(element);
+ return true;
+ }
+ // need to check in fragments for the classpath entry.
+ // only check for fragments if the data is the host's data.
+ if (hostloader.data == sourcedata)
+ for (int i = 0; i < hostloader.fragments.length; i++) {
+ FragmentClasspath fragCP = hostloader.fragments[i];
+ element = hostloader.getClasspath(cp, fragCP.getBundleData(), fragCP.getDomain());
+ if (element != null) {
+ result.add(element);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Creates a new ClasspathEntry object for the requested classpath if the source exists.
+ * @param cp the requested classpath.
+ * @param sourcedata the source EquionoxData to search for the classpath
+ * @param sourcedomain the source domain to used by the new ClasspathEntry
+ * @return a new ClasspathEntry for the requested classpath or null if the source does not exist.
+ */
+ public ClasspathEntry getClasspath(String cp, BaseData sourcedata, ProtectionDomain sourcedomain) {
+ BundleFile bundlefile = null;
+ File file;
+ // check for internal library jars
+ if ((file = sourcedata.getBundleFile().getFile(cp, false)) != null)
+ bundlefile = createBundleFile(file, sourcedata);
+ // check for internal library directories in a bundle jar file
+ if (bundlefile == null && sourcedata.getBundleFile().containsDir(cp))
+ bundlefile = new NestedDirBundleFile(sourcedata.getBundleFile(), cp);
+ // if in dev mode, try using the cp as an absolute path
+ if (bundlefile != null)
+ return createClassPathEntry(bundlefile, sourcedomain);
+ return null;
+ }
+
+ /**
+ * Uses the requested classpath as an absolute path to locate a source for a new ClasspathEntry.
+ * @param cp the requested classpath
+ * @param sourcedata the source EquionoxData to search for the classpath
+ * @param sourcedomain the source domain to used by the new ClasspathEntry
+ * @return a classpath entry which uses an absolut path as a source
+ */
+ public ClasspathEntry getExternalClassPath(String cp, BaseData sourcedata, ProtectionDomain sourcedomain) {
+ File file = new File(cp);
+ if (!file.isAbsolute())
+ return null;
+ BundleFile bundlefile = createBundleFile(file, sourcedata);
+ if (bundlefile != null)
+ return createClassPathEntry(bundlefile, sourcedomain);
+ return null;
+ }
+
+ private static BundleFile createBundleFile(File file, BaseData sourcedata) {
+ if (file == null || !file.exists())
+ return null;
+ try {
+ return sourcedata.getAdaptor().createBundleFile(file, sourcedata);
+ } catch (IOException e) {
+ sourcedata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, sourcedata.getBundle(), e);
+ }
+ return null;
+ }
+
+ private ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain cpDomain) {
+ return classloader.createClassPathEntry(bundlefile, cpDomain);
+ }
+
+ /**
+ * Finds a local resource by searching the ClasspathEntry objects of the classpath manager.
+ * This method will first call all the configured class loading stats hooks
+ * {@link ClassLoadingStatsHook#preFindLocalResource(String, ClasspathManager)} methods. Then it
+ * will search for the resource. Finally it will call all the configured class loading stats hooks
+ * {@link ClassLoadingStatsHook#postFindLocalResource(String, URL, ClasspathManager)} methods.
+ * @param resource the requested resource name.
+ * @return the requested resource URL or null if the resource does not exist
+ */
+ public URL findLocalResource(String resource) {
+ ClassLoadingStatsHook[] hooks = data.getAdaptor().getHookRegistry().getClassLoadingStatsHooks();
+ for (int i = 0; i < hooks.length; i++)
+ hooks[i].preFindLocalResource(resource, this);
+ URL result = null;
+ try {
+ result = findLocalResourceImpl(resource);
+ return result;
+ } finally {
+ for (int i = 0; i < hooks.length; i++)
+ hooks[i].postFindLocalResource(resource, result, this);
+ }
+ }
+
+ private URL findLocalResourceImpl(String resource) {
+ URL result = null;
+ for (int i = 0; i < entries.length; i++) {
+ if (entries[i] != null) {
+ result = findResourceImpl(resource, entries[i].getBundleFile());
+ if (result != null)
+ return result;
+ }
+ }
+ // look in fragments
+ for (int i = 0; i < fragments.length; i++) {
+ ClasspathEntry[] fragEntries = fragments[i].getEntries();
+ for (int j = 0; j < fragEntries.length; j++) {
+ result = findResourceImpl(resource, fragEntries[j].getBundleFile());
+ if (result != null)
+ return result;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Finds the local resources by searching the ClasspathEntry objects of the classpath manager.
+ * @param resource the requested resource name.
+ * @return an enumeration of the the requested resources or null if the resources do not exist
+ */
+ public Enumeration findLocalResources(String resource) {
+ Vector resources = new Vector(6); // use a Vector instead of ArrayList because we need an enumeration
+ for (int i = 0; i < entries.length; i++) {
+ if (entries[i] != null) {
+ URL url = findResourceImpl(resource, entries[i].getBundleFile(), resources.size());
+ if (url != null)
+ resources.addElement(url);
+ }
+ }
+ // look in fragments
+ for (int i = 0; i < fragments.length; i++) {
+ ClasspathEntry[] fragEntries = fragments[i].getEntries();
+ for (int j = 0; j < fragEntries.length; j++) {
+ URL url = findResourceImpl(resource, fragEntries[j].getBundleFile(), resources.size());
+ if (url != null)
+ resources.addElement(url);
+ }
+ }
+ if (resources.size() > 0)
+ return resources.elements();
+ return null;
+ }
+
+ private URL findResourceImpl(String name, BundleFile bundlefile) {
+ return findResourceImpl(name, bundlefile, 0);
+ }
+
+ private URL findResourceImpl(String name, BundleFile bundlefile, int index) {
+ return bundlefile.getResourceURL(name, data.getBundleID(), index);
+ }
+
+ /**
+ * Finds a local entry by searching the ClasspathEntry objects of the classpath manager.
+ * @param path the requested entry path.
+ * @return the requested entry or null if the entry does not exist
+ */
+ public BundleEntry findLocalEntry(String path) {
+ BundleEntry result = null;
+ for (int i = 0; i < entries.length; i++) {
+ if (entries[i] != null) {
+ result = findEntryImpl(path, entries[i].getBundleFile());
+ if (result != null)
+ return result;
+ }
+ }
+ // look in fragments
+ for (int i = 0; i < fragments.length; i++) {
+ ClasspathEntry[] fragEntries = fragments[i].getEntries();
+ for (int j = 0; j < fragEntries.length; j++) {
+ result = findEntryImpl(path, fragEntries[j].getBundleFile());
+ if (result != null)
+ return result;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Finds the local entries by searching the ClasspathEntry objects of the classpath manager.
+ * @param path the requested entry path.
+ * @return an enumeration of the the requested entries or null if the entries do not exist
+ */
+ public Enumeration findLocalEntries(String path) {
+ Vector objects = new Vector(6); // use a Vector instead of ArrayList because we need an enumeration
+ for (int i = 0; i < entries.length; i++) {
+ if (entries[i] != null) {
+ BundleEntry result = findEntryImpl(path, entries[i].getBundleFile());
+ if (result != null)
+ objects.addElement(result);
+ }
+ }
+ // look in fragments
+ for (int i = 0; i < fragments.length; i++) {
+ ClasspathEntry[] fragEntries = fragments[i].getEntries();
+ for (int j = 0; j < fragEntries.length; j++) {
+ BundleEntry result = findEntryImpl(path, fragEntries[j].getBundleFile());
+ if (result != null)
+ objects.addElement(result);
+ }
+ }
+ if (objects.size() > 0)
+ return objects.elements();
+ return null;
+ }
+
+ private BundleEntry findEntryImpl(String path, BundleFile bundleFile) {
+ return bundleFile.getEntry(path);
+ }
+
+ /**
+ * Finds a local class by searching the ClasspathEntry objects of the classpath manager.
+ * This method will first call all the configured class loading stats hooks
+ * {@link ClassLoadingStatsHook#preFindLocalClass(String, ClasspathManager)} methods. Then it
+ * will search for the class. If a class is found then all configured class loading hooks
+ * {@link ClassLoadingHook#processClass(String, byte[], ClasspathEntry, BundleEntry, ClasspathManager)}
+ * methods will be called. Finally all the configured class loading stats hooks
+ * {@link ClassLoadingStatsHook#postFindLocalClass(String, Class, ClasspathManager)} methods are called.
+ * @param classname the requested class name.
+ * @return the requested class
+ * @throws ClassNotFoundException if the class does not exist
+ */
+ public Class findLocalClass(String classname) throws ClassNotFoundException {
+ Class result = null;
+ ClassLoadingStatsHook[] hooks = data.getAdaptor().getHookRegistry().getClassLoadingStatsHooks();
+ try {
+ for (int i = 0; i < hooks.length; i++)
+ hooks[i].preFindLocalClass(classname, this);
+ result = findLocalClassImpl(classname, hooks);
+ return result;
+ } finally {
+ for (int i = 0; i < hooks.length; i++)
+ hooks[i].postFindLocalClass(classname, result, this);
+ }
+ }
+
+ private Class findLocalClassImpl(String classname, ClassLoadingStatsHook[] hooks) throws ClassNotFoundException {
+ // must call findLoadedClass here even if it was called earlier,
+ // the findLoadedClass and defineClass calls must be atomic
+ synchronized (classloader) {
+ Class result = classloader.publicFindLoaded(classname);
+ if (result != null)
+ return result;
+ for (int i = 0; i < entries.length; i++) {
+ if (entries[i] != null) {
+ result = findClassImpl(classname, entries[i], hooks);
+ if (result != null)
+ return result;
+ }
+ }
+ // look in fragments.
+ for (int i = 0; i < fragments.length; i++) {
+ ClasspathEntry[] fragEntries = fragments[i].getEntries();
+ for (int j = 0; j < fragEntries.length; j++) {
+ result = findClassImpl(classname, fragEntries[j], hooks);
+ if (result != null)
+ return result;
+ }
+ }
+ }
+ throw new ClassNotFoundException(classname);
+ }
+
+ private Class findClassImpl(String name, ClasspathEntry classpathEntry, ClassLoadingStatsHook[] hooks) {
+ if (Debug.DEBUG && Debug.DEBUG_LOADER)
+ Debug.println("BundleClassLoader[" + data + "].findClass(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
+ String filename = name.replace('.', '/').concat(".class"); //$NON-NLS-1$
+ BundleEntry entry = classpathEntry.getBundleFile().getEntry(filename);
+ if (entry == null)
+ return null;
+
+ InputStream in;
+ try {
+ in = entry.getInputStream();
+ } catch (IOException e) {
+ return null;
+ }
+
+ int length = (int) entry.getSize();
+ byte[] classbytes;
+ int bytesread = 0;
+ int readcount;
+ if (Debug.DEBUG && Debug.DEBUG_LOADER)
+ Debug.println(" about to read " + length + " bytes from " + filename); //$NON-NLS-1$ //$NON-NLS-2$
+
+ try {
+ try {
+ if (length > 0) {
+ classbytes = new byte[length];
+ readloop: for (; bytesread < length; bytesread += readcount) {
+ readcount = in.read(classbytes, bytesread, length - bytesread);
+ if (readcount <= 0) /* if we didn't read anything */
+ break readloop; /* leave the loop */
+ }
+ } else /* BundleEntry does not know its own length! */{
+ length = BUF_SIZE;
+ classbytes = new byte[length];
+ readloop: while (true) {
+ for (; bytesread < length; bytesread += readcount) {
+ readcount = in.read(classbytes, bytesread, length - bytesread);
+ if (readcount <= 0) /* if we didn't read anything */
+ break readloop; /* leave the loop */
+ }
+ byte[] oldbytes = classbytes;
+ length += BUF_SIZE;
+ classbytes = new byte[length];
+ System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
+ }
+ }
+ if (classbytes.length > bytesread) {
+ byte[] oldbytes = classbytes;
+ classbytes = new byte[bytesread];
+ System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
+ }
+ } catch (IOException e) {
+ if (Debug.DEBUG && Debug.DEBUG_LOADER)
+ Debug.println(" IOException reading " + filename + " from " + data); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+ } finally {
+ try {
+ in.close();
+ } catch (IOException ee) {
+ // nothing to do here
+ }
+ }
+
+ if (Debug.DEBUG && Debug.DEBUG_LOADER) {
+ Debug.println(" read " + bytesread + " bytes from " + filename); //$NON-NLS-1$ //$NON-NLS-2$
+ Debug.println(" defining class " + name); //$NON-NLS-1$
+ }
+
+ try {
+ Class result = defineClass(name, classbytes, classpathEntry, entry);
+ for (int i = 0; i < hooks.length; i++)
+ hooks[i].recordClassDefine(name, result, classbytes, classpathEntry, entry, this);
+ return result;
+ } catch (Error e) {
+ if (Debug.DEBUG && Debug.DEBUG_LOADER)
+ Debug.println(" error defining class " + name); //$NON-NLS-1$
+ throw e;
+ }
+ }
+
+ /**
+ * Defines the specified class. This method will first call all the configured class loading hooks
+ * {@link ClassLoadingHook#processClass(String, byte[], ClasspathEntry, BundleEntry, ClasspathManager)}
+ * methods. Then it will call the {@link BaseClassLoader#defineClass(String, byte[], ClasspathEntry, BundleEntry)}
+ * method to define the class.
+ * @param name the name of the class to define
+ * @param classbytes the class bytes
+ * @param classpathEntry the classpath entry used to load the class bytes
+ * @param entry the BundleEntry used to load the class bytes
+ * @return the defined class
+ */
+ private Class defineClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry) {
+ ClassLoadingHook[] hooks = data.getAdaptor().getHookRegistry().getClassLoadingHooks();
+ byte[] modifiedBytes = classbytes;
+ for (int i = 0; i < hooks.length; i++) {
+ modifiedBytes = hooks[i].processClass(name, classbytes, classpathEntry, entry, this);
+ if (modifiedBytes != null)
+ classbytes = modifiedBytes;
+ }
+ return classloader.defineClass(name, classbytes, classpathEntry, entry);
+ }
+
+ /**
+ * Returns the host base data for this classpath manager
+ * @return the host base data for this classpath manager
+ */
+ public BaseData getBaseData() {
+ return data;
+ }
+
+ /**
+ * Returns the fragment classpaths of this classpath manager
+ * @return the fragment classpaths of this classpath manager
+ */
+ public FragmentClasspath[] getFragmentClasspaths() {
+ return fragments;
+ }
+
+ /**
+ * Returns the host classpath entries for this classpath manager
+ * @return the host classpath entries for this classpath manager
+ */
+ public ClasspathEntry[] getHostClasspathEntries() {
+ return entries;
+ }
+
+ /**
+ * Returns the base class loader used by this classpath manager
+ * @return the base class loader used by this classpath manager
+ */
+ public BaseClassLoader getBaseClassLoader() {
+ return classloader;
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/FragmentClasspath.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/FragmentClasspath.java
new file mode 100644
index 000000000..89ae2cfde
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/FragmentClasspath.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.baseadaptor.loader;
+
+import java.io.IOException;
+import java.security.ProtectionDomain;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.osgi.framework.FrameworkEvent;
+
+/**
+ * A FragmentClasspath contains all the <code>ClasspathEntry</code> objects for a fragment
+ * <code>BaseData</code>.
+ */
+public class FragmentClasspath {
+ private BaseData bundledata;
+ private ClasspathEntry[] entries;
+ private ProtectionDomain domain;
+
+ public FragmentClasspath(BaseData bundledata, ClasspathEntry[] entries, ProtectionDomain domain) {
+ this.bundledata = bundledata;
+ this.entries = entries;
+ this.domain = domain;
+ }
+
+ /**
+ * Returns the fragment BaseData for this FragmentClasspath
+ * @return the fragment BaseData for this FragmentClasspath
+ */
+ public BaseData getBundleData() {
+ return bundledata;
+ }
+
+ /**
+ * Returns the fragment domain for this FragmentClasspath
+ * @return the fragment domain for this FragmentClasspath
+ */
+ public ProtectionDomain getDomain() {
+ return domain;
+ }
+
+ /**
+ * Returns the fragment classpath entries for this FragmentClasspath
+ * @return the fragment classpath entries for this FragmentClasspath
+ */
+ public ClasspathEntry[] getEntries() {
+ return entries;
+ }
+
+ /**
+ * Closes all the classpath entry resources for this FragmentClasspath.
+ *
+ */
+ public void close() {
+ for (int i = 0; i < entries.length; i++) {
+ try {
+ entries[i].getBundleFile().close();
+ } catch (IOException e) {
+ bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e);
+ }
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractBundleData.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractBundleData.java
deleted file mode 100644
index e5d660599..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractBundleData.java
+++ /dev/null
@@ -1,846 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.adaptor.core;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.*;
-import org.eclipse.osgi.framework.adaptor.*;
-import org.eclipse.osgi.framework.debug.Debug;
-import org.eclipse.osgi.framework.internal.core.Constants;
-import org.eclipse.osgi.framework.internal.protocol.bundleentry.Handler;
-import org.eclipse.osgi.framework.util.Headers;
-import org.eclipse.osgi.util.ManifestElement;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.*;
-
-/**
- * An abstract BundleData class that has default implementations that most
- * BundleData implementations can use.
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.1
- */
-public abstract class AbstractBundleData implements BundleData, Cloneable {
-
- /** the Adaptor for this BundleData */
- protected AbstractFrameworkAdaptor adaptor;
-
- /**
- * The Bundle Manifest for this BundleData.
- */
- protected Dictionary manifest = null;
-
- /**
- * The Bundle object for this BundleData.
- */
- protected Bundle bundle;
-
- /** bundle id */
- protected long id;
-
- /** The top level storage directory for the BundleData */
- protected File bundleStoreDir;
-
- /** The base BundleFile object for this BundleData */
- protected BundleFile baseBundleFile;
- ///////////////////// Begin Meta Data for the Bundle /////////////////////
-
- /** bundle location */
- private String location;
-
- /** bundle's file name */
- private String fileName;
-
- /** native code paths for this BundleData */
- private String[] nativePaths;
-
- /** bundle generation */
- private int generation = 1;
-
- /** the bundles start level */
- private int startLevel = -1;
-
- /**
- * The BundleData data directory
- */
- protected File dirData;
-
- /** the bundles status */
- private int status = 0;
-
- /** Is bundle a reference */
- private boolean reference;
-
- /** the bundles last modified timestamp */
- private long lastModified;
-
- ///////////////////// End Meta Data for the Bundle /////////////////////
-
- ///////////////////// Begin values from Manifest /////////////////////
- private String symbolicName;
- private Version version;
- private String activator;
- private String classpath;
- private String executionEnvironment;
- private String dynamicImports;
- private int type;
-
- ///////////////////// End values from Manifest /////////////////////
-
- /**
- * Constructor for AbstractBundleData
- * @param adaptor The adaptor for this bundle data
- * @param id The bundle id for this bundle data
- */
- public AbstractBundleData(AbstractFrameworkAdaptor adaptor, long id) {
- this.adaptor = adaptor;
- this.id = id;
- initBundleStoreDirs(String.valueOf(id));
- }
-
- /**
- * @see BundleData#getManifest()
- */
- public Dictionary getManifest() throws BundleException {
- if (manifest == null) {
- synchronized (this) {
- // make sure the manifest is still null after we have aquired the lock.
- if (manifest == null) {
- URL url = getEntry(Constants.OSGI_BUNDLE_MANIFEST);
- if (url == null) {
- throw new BundleException(NLS.bind(AdaptorMsg.MANIFEST_NOT_FOUND_EXCEPTION, Constants.OSGI_BUNDLE_MANIFEST, getLocation()));
- }
- try {
- manifest = Headers.parseManifest(url.openStream());
- } catch (IOException e) {
- throw new BundleException(NLS.bind(AdaptorMsg.MANIFEST_NOT_FOUND_EXCEPTION, Constants.OSGI_BUNDLE_MANIFEST, getLocation()), e);
- }
- }
- }
- }
- return manifest;
- }
-
- /**
- * @see BundleData#setBundle(Bundle)
- */
- public void setBundle(Bundle bundle) {
- this.bundle = bundle;
- }
-
- /**
- * Returns the Bundle object for this BundleData.
- * @return the Bundle object for this BundleData.
- */
- public Bundle getBundle() {
- return bundle;
- }
-
- /**
- * @see BundleData#getBundleID()
- */
- public long getBundleID() {
- return (id);
- }
-
- /**
- * @see BundleData#getEntry(String)
- */
- public URL getEntry(String path) {
- BundleEntry entry = getBaseBundleFile().getEntry(path);
- if (entry == null) {
- return null;
- }
- if (path.length() == 0 || path.charAt(0) != '/')
- path = path = '/' + path;
- try {
- //use the constant string for the protocol to prevent duplication
- return new URL(Constants.OSGI_ENTRY_URL_PROTOCOL, Long.toString(id), 0, path, new Handler(entry));
- } catch (MalformedURLException e) {
- return null;
- }
- }
-
- /**
- * @see BundleData#getEntryPaths(String)
- */
- public Enumeration getEntryPaths(String path) {
- return getBaseBundleFile().getEntryPaths(path);
- }
-
- /**
- * @see BundleData#createClassLoader(ClassLoaderDelegate, BundleProtectionDomain, String[])
- */
- public org.eclipse.osgi.framework.adaptor.BundleClassLoader createClassLoader(ClassLoaderDelegate delegate, BundleProtectionDomain domain, String[] bundleclasspath) {
- return getAdaptor().getElementFactory().createClassLoader(delegate, domain, bundleclasspath, this);
- }
-
- /**
- * Returns the adaptor for this bundle data.
- * @return the adaptor for this bundle data.
- */
- public AbstractFrameworkAdaptor getAdaptor() {
- return adaptor;
- }
-
- /**
- * Returns a list of classpath entries from a list of manifest elements
- * @param classpath a list of ManifestElement objects
- * @return a list of classpath entries from a list of manifest elements
- */
- static String[] getClassPath(ManifestElement[] classpath) {
- if (classpath == null) {
- if (Debug.DEBUG && Debug.DEBUG_LOADER)
- Debug.println(" no classpath"); //$NON-NLS-1$
- /* create default BundleClassPath */
- return new String[] {"."}; //$NON-NLS-1$
- }
-
- ArrayList result = new ArrayList(classpath.length);
- for (int i = 0; i < classpath.length; i++) {
- if (Debug.DEBUG && Debug.DEBUG_LOADER)
- Debug.println(" found classpath entry " + classpath[i].getValueComponents()); //$NON-NLS-1$
- String[] paths = classpath[i].getValueComponents();
- for (int j = 0; j < paths.length; j++) {
- result.add(paths[j]);
- }
- }
-
- return (String[]) result.toArray(new String[result.size()]);
- }
-
- ///////////////////// Begin Meta Data Accessor Methods ////////////////////
- /**
- * @see BundleData#getLocation()
- */
- public String getLocation() {
- return location;
- }
- /**
- * Sets the location for this bundle data
- * @param location the location string
- */
- public void setLocation(String location) {
- this.location = location;
- }
-
- /**
- * Returns the filename for the base file of this bundle data
- * @return the filename for the base file of this bundle data
- */
- public String getFileName() {
- return fileName;
- }
-
- /**
- * Sets the filename for the base file of this bundle data
- * @param fileName the name of the base file of this bundle data
- */
- public void setFileName(String fileName) {
- this.fileName = fileName;
- }
-
- /**
- * Returns the list of native file paths to install for this bundle
- * @return the list of native file paths to install for this bundle
- */
- public String[] getNativePaths() {
- return nativePaths;
- }
-
- /**
- * Returns a comma separated list of native file paths to install for this bundle
- * @return a comma separated list of native file paths to install for this bundle
- */
- public String getNativePathsString() {
- if (nativePaths == null || nativePaths.length == 0)
- return null;
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < nativePaths.length; i++) {
- sb.append(nativePaths[i]);
- if (i < nativePaths.length - 1)
- sb.append(',');
- }
- return sb.toString();
- }
-
- /**
- * Sets the list of native file paths to install for this bundle
- * @param nativePaths the list of native file paths to install for this bundle
- */
- public void setNativePaths(String[] nativePaths) {
- this.nativePaths = nativePaths;
- }
-
- /**
- * Sets the comma separated list of native file paths to install for this bundle
- * @param nativePaths the comma separated list of native file paths to install for this bundle
- */
- public void setNativePaths(String nativePaths) {
- if (nativePaths == null)
- return;
- ArrayList result = new ArrayList(5);
- StringTokenizer st = new StringTokenizer(nativePaths, ","); //$NON-NLS-1$
- while (st.hasMoreTokens()) {
- String path = st.nextToken();
- result.add(path);
- }
- setNativePaths((String[]) result.toArray(new String[result.size()]));
- }
-
- /**
- * Returns the generation number for this bundle
- * @return the generation number for this bundle
- */
- public int getGeneration() {
- return generation;
- }
-
- /**
- * Sets the generation number for this bundle
- * @param generation the generation number for this bundle
- */
- public void setGeneration(int generation) {
- this.generation = generation;
- }
-
- /**
- * @see BundleData#getLastModified()
- */
- public long getLastModified() {
- return lastModified;
- }
-
- /**
- * Sets the last modified timestamp for this bundle
- * @param lastModified the last modified timestamp for this bundle
- */
- public void setLastModified(long lastModified) {
- this.lastModified = lastModified;
- }
-
- /**
- * @see BundleData#getStartLevel()
- */
- public int getStartLevel() {
- return startLevel;
- }
-
- /**
- * @see BundleData#setStartLevel(int)
- */
- public void setStartLevel(int startLevel) {
- this.startLevel = startLevel;
- }
-
- /**
- * @see BundleData#getStatus()
- */
- public int getStatus() {
- return status;
- }
-
- /**
- * @see BundleData#setStatus(int)
- */
- public void setStatus(int status) {
- this.status = status;
- }
-
- /**
- * Returns if this bundle is installed by reference
- * @return true if this bundle is installed by reference
- */
- public boolean isReference() {
- return reference;
- }
-
- /**
- * Sets if this bundle is installed by reference
- * @param reference indicates if this bundle is installed by reference
- */
- public void setReference(boolean reference) {
- this.reference = reference;
- }
-
- ///////////////////// End Meta Data Accessor Methods ////////////////////
-
- ///////////////////// Begin Manifest Value Accessor Methods /////////////////////
-
- /**
- * @see BundleData#getSymbolicName()
- */
- public String getSymbolicName() {
- return symbolicName;
- }
-
- /**
- * Returns the base storage directory for this bundle
- * @return the base storage directory for this bundle
- */
- public File getBundleStoreDir() {
- return bundleStoreDir;
- }
-
- /**
- * Sets the symbolic name of this bundle
- * @param symbolicName the symbolic name of this bundle
- */
- public void setSymbolicName(String symbolicName) {
- this.symbolicName = symbolicName;
- }
-
- /**
- * Loads all metadata for this bundle from the bundle manifest
- * @throws BundleException
- */
- protected void loadFromManifest() throws BundleException {
- getManifest();
- if (manifest == null)
- throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_ERROR_GETTING_MANIFEST, getLocation()));
- try {
- setVersion(Version.parseVersion((String) manifest.get(Constants.BUNDLE_VERSION)));
- } catch (IllegalArgumentException e) {
- setVersion(new InvalidVersion((String) manifest.get(Constants.BUNDLE_VERSION)));
- }
- ManifestElement[] bsnHeader = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME));
- int bundleType = 0;
- if (bsnHeader != null) {
- setSymbolicName(bsnHeader[0].getValue());
- String singleton = bsnHeader[0].getDirective(Constants.SINGLETON_DIRECTIVE);
- if (singleton == null)
- singleton = bsnHeader[0].getAttribute(Constants.SINGLETON_DIRECTIVE);
- if ("true".equals(singleton)) //$NON-NLS-1$
- bundleType |= TYPE_SINGLETON;
- }
- setClassPathString((String) manifest.get(Constants.BUNDLE_CLASSPATH));
- setActivator((String) manifest.get(Constants.BUNDLE_ACTIVATOR));
- String host = (String) manifest.get(Constants.FRAGMENT_HOST);
- if (host != null) {
- bundleType |= TYPE_FRAGMENT;
- ManifestElement[] hostElement = ManifestElement.parseHeader(Constants.FRAGMENT_HOST, host);
- if (Constants.getInternalSymbolicName().equals(hostElement[0].getValue()) || Constants.OSGI_SYSTEM_BUNDLE.equals(hostElement[0].getValue())) {
- String extensionType = hostElement[0].getDirective("extension"); //$NON-NLS-1$
- if (extensionType == null || extensionType.equals("framework")) //$NON-NLS-1$
- bundleType |= TYPE_FRAMEWORK_EXTENSION;
- else
- bundleType |= TYPE_BOOTCLASSPATH_EXTENSION;
- }
- }
- setType(bundleType);
- setExecutionEnvironment((String) manifest.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT));
- setDynamicImports((String) manifest.get(Constants.DYNAMICIMPORT_PACKAGE));
- }
-
- /**
- * @see BundleData#getVersion()
- */
- public Version getVersion() {
- return version;
- }
-
- /**
- * Sets the version of this bundle
- * @param version the version of this bundle
- */
- public void setVersion(Version version) {
- this.version = version;
- }
-
- /**
- * @see BundleData#getActivator()
- */
- public String getActivator() {
- return activator;
- }
-
- /**
- * Returns the data storage directory for this bundle
- * @return the data storage directory for this bundle
- */
- protected File getDataDir() {
- return dirData;
- }
-
- /**
- * Sets the bundle store directory for this bundle
- * @param bundleStoreDir the store directory for this bundle
- */
- protected void setBundleStoreDir(File bundleStoreDir) {
- this.bundleStoreDir = bundleStoreDir;
- }
-
- /**
- * Sets the initial bundle store directory according to the bundle ID
- * @param bundleID the bundle ID
- */
- protected void initBundleStoreDirs(String bundleID) {
- setBundleStoreDir(new File(((AbstractFrameworkAdaptor) adaptor).getBundleStoreRootDir(), bundleID));
- }
-
- /**
- * Sets the activator for this bundle
- * @param activator the activator for this bundle
- */
- public void setActivator(String activator) {
- this.activator = activator;
- }
-
- /**
- * @see BundleData#getClassPath()
- */
- public String[] getClassPath() throws BundleException {
- ManifestElement[] classpathElements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, classpath);
- return getClassPath(classpathElements);
- }
-
- /**
- * Returns the Bundle-ClassPath value as specified in the bundle manifest file.
- * @return the Bundle-ClassPath value as specified in the bundle manifest file.
- */
- public String getClassPathString() {
- return classpath;
- }
-
- /**
- * Sets the bundle classpath value of this bundle data.
- * @param classpath the bundle classpath
- */
- public void setClassPathString(String classpath) {
- this.classpath = classpath;
- }
-
- /**
- * @see BundleData#getExecutionEnvironment()
- */
- public String getExecutionEnvironment() {
- return executionEnvironment;
- }
-
- /**
- * Sets the execution environment for this bundle
- * @param executionEnvironment the execution environment for this bundle
- */
- public void setExecutionEnvironment(String executionEnvironment) {
- this.executionEnvironment = executionEnvironment;
- }
-
- /**
- * @see BundleData#getDynamicImports()
- */
- public String getDynamicImports() {
- return dynamicImports;
- }
-
- /**
- * Sets the dynamic imports of this bundle data.
- * @param dynamicImports the dynamic imports
- */
- public void setDynamicImports(String dynamicImports) {
- this.dynamicImports = dynamicImports;
- }
-
- /**
- * @see BundleData#getType()
- */
- public int getType() {
- return type;
- }
-
- /**
- * Sets the type of this bundle
- * @param type the type of this bundle
- */
- public void setType(int type) {
- this.type = type;
- }
-
- ///////////////////// End Manifest Value Accessor Methods /////////////////////
-
- /**
- * @see BundleData#matchDNChain(String)
- */
- public boolean matchDNChain(String pattern) {
- if (System.getSecurityManager() == null)
- return false;
-
- if (getBaseBundleFile() instanceof SignedBundle)
- return ((SignedBundle) getBaseBundleFile()).matchDNChain(pattern);
- return false;
- }
-
- /**
- * Return a copy of this object with the
- * generation dependent fields updated to
- * the next free generation level.
- *
- * @throws IOException If there are no more available generation levels.
- */
- protected AbstractBundleData nextGeneration(String referenceFile) throws IOException {
- int nextGeneration = getGeneration();
-
- while (nextGeneration < Integer.MAX_VALUE) {
- nextGeneration++;
-
- File nextDirGeneration = new File(getBundleStoreDir(), String.valueOf(nextGeneration));
-
- if (nextDirGeneration.exists()) {
- continue;
- }
-
- AbstractBundleData next;
- try {
- next = (AbstractBundleData) clone();
- } catch (CloneNotSupportedException e) {
- // this shouldn't happen, since we are Cloneable
- throw new InternalError();
- }
-
- next.setGeneration(nextGeneration);
-
- if (referenceFile != null) {
- next.setReference(true);
- next.setFileName(referenceFile);
- } else {
- if (next.isReference()) {
- next.setReference(false);
- next.setFileName(AbstractFrameworkAdaptor.BUNDLEFILE_NAME);
- }
- }
-
- // null out the manifest to force it to be re-read.
- next.manifest = null;
- return (next);
- }
-
- throw new IOException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION);
- }
-
- /**
- * Initializes a new bundle and loads all its metadata from the bundle manifest
- * @throws IOException
- * @throws BundleException
- */
- public void initializeNewBundle() throws IOException, BundleException {
- createBaseBundleFile();
- loadFromManifest();
- }
-
- /**
- * Creates the base BundleFile for this bundle
- * @return the base BundleFile for this bundle
- * @throws IOException if an IOExceptions occurs
- */
- protected BundleFile createBaseBundleFile() throws IOException {
- baseBundleFile = getAdaptor().createBaseBundleFile(getBaseFile(), this);
- return baseBundleFile;
- }
-
- /**
- * Return the base File for the bundle.
- * Attempt to create the bundle generation directory if it does not exist.
- *
- * @return the base File object for the bundle.
- */
- protected File getBaseFile() {
- return isReference() ? new File(getFileName()) : new File(createGenerationDir(), getFileName());
- }
-
- /**
- * Returns a list of files used for the classpath of this bundle data.
- * the contents of the bundle are searched for the classpath entries.
- * @param classpaths the classpath entries to search for
- * @return a list of files used for the classpath of this bundle data.
- */
- protected File[] getClasspathFiles(String[] classpaths) {
- ArrayList results = new ArrayList(classpaths.length);
- for (int i = 0; i < classpaths.length; i++) {
- if (".".equals(classpaths[i])) //$NON-NLS-1$
- results.add(getBaseFile());
- else {
- File result = getBaseBundleFile().getFile(classpaths[i]);
- if (result != null)
- results.add(result);
- }
- }
- return (File[]) results.toArray(new File[results.size()]);
- }
-
- /**
- * Sets the data directory for this bundle
- * @param dirData the data directory for this bundle
- */
- protected void setDataDir(File dirData) {
- this.dirData = dirData;
- }
-
- /**
- * @see BundleData#findLibrary(String)
- */
- public String findLibrary(String libname) {
- String mappedName = System.mapLibraryName(libname);
- String path = null;
-
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println(" mapped library name: " + mappedName); //$NON-NLS-1$
- }
-
- path = findNativePath(mappedName);
-
- if (path == null) {
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println(" library does not exist: " + mappedName); //$NON-NLS-1$
- }
- path = findNativePath(libname);
- }
-
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println(" returning library: " + path); //$NON-NLS-1$
- }
- return path;
- }
-
- /**
- * @see BundleData#open()
- */
- public void open() throws IOException {
- baseBundleFile.open();
- }
-
- /**
- * Searches the native paths for a match against the specified libname.
- * If a match is found then the native path is returned; otherwise a
- * <code>null</code> value is returned.
- * @param libname a library name
- * @return a matching native path or <code>null</code>.
- */
- protected String findNativePath(String libname) {
- int slash = libname.lastIndexOf('/');
- if (slash >= 0)
- libname = libname.substring(slash + 1);
- String[] nativepaths = getNativePaths();
- if (nativepaths != null) {
- for (int i = 0; i < nativepaths.length; i++) {
- slash = nativepaths[i].lastIndexOf('/');
- String path = slash < 0 ? nativePaths[i] : nativePaths[i].substring(slash + 1);
- if (path.equals(libname)) {
- File nativeFile = baseBundleFile.getFile(nativepaths[i]);
- if (nativeFile != null)
- return nativeFile.getAbsolutePath();
- }
- }
- }
- return null;
- }
-
- /**
- * Return the generation directory for the bundle data. The generation
- * directory can be used by the framework to cache files from the bundle
- * to the file system. Attempt to create the directory if it does not exist.
- * @return The generation directory for the bundle data or null if not
- * supported.
- */
- public File createGenerationDir() {
- File generationDir = getGenerationDir();
- if (!generationDir.exists() && (!adaptor.canWrite() || !generationDir.mkdirs())) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to create bundle generation directory: " + generationDir.getPath()); //$NON-NLS-1$
- }
- }
-
- return generationDir;
- }
-
- /**
- * Return the base BundleFile for this BundleData. The base BundleFile
- * is the BundleFile that contains all the content of the bundle.
- * @return the base BundleFile.
- */
- public BundleFile getBaseBundleFile() {
- return baseBundleFile;
- }
-
- /**
- * Close all resources for this BundleData
- */
- public void close() throws IOException {
- if (baseBundleFile != null) {
- baseBundleFile.close();
- }
- }
-
- /**
- * Return the bundle data directory.
- * Attempt to create the directory if it does not exist.
- *
- * @return Bundle data directory.
- */
- public File getDataFile(String path) {
- // lazily initialize dirData to prevent early access to configuration location
- if (getDataDir() == null) {
- File dataRoot = adaptor.getDataRootDir();
- if (dataRoot == null)
- throw new IllegalStateException(AdaptorMsg.ADAPTOR_DATA_AREA_NOT_SET);
- setDataDir(new File(dataRoot, id + "/" + AbstractFrameworkAdaptor.DATA_DIR_NAME)); //$NON-NLS-1$
- }
- if (!getDataDir().exists() && (!adaptor.canWrite() || !getDataDir().mkdirs())) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to create bundle data directory: " + getDataDir().getPath()); //$NON-NLS-1$
- }
- }
-
- return (new File(getDataDir(), path));
- }
-
- /**
- * @see BundleData#installNativeCode(String[])
- */
- public void installNativeCode(String[] nativepaths) throws BundleException {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < nativepaths.length; i++) {
- // extract the native code
- File nativeFile = baseBundleFile.getFile(nativepaths[i]);
- if (nativeFile == null) {
- throw new BundleException(NLS.bind(AdaptorMsg.BUNDLE_NATIVECODE_EXCEPTION, nativepaths[i]));
- }
- sb.append(nativepaths[i]);
- if (i < nativepaths.length - 1) {
- sb.append(","); //$NON-NLS-1$
- }
- }
- if (sb.length() > 0)
- setNativePaths(sb.toString());
- }
-
- /**
- * Returns the generation directory for the bundle data. The returned
- * file may not exist.
- * @return the generation directory for the bundle data.
- */
- protected File getGenerationDir() {
- return new File(getBundleStoreDir(), String.valueOf(getGeneration()));
- }
-
- /**
- * Returns the parent generation directory for the bundle data. The returned
- * file may not exist. A value of <code>null</code> is returned if there is
- * no parent generation directory.
- * @return the parent gneration directory for the bundle data.
- */
- public File getParentGenerationDir() {
- return null;
- }
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractClassLoader.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractClassLoader.java
deleted file mode 100644
index c591f4469..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractClassLoader.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.adaptor.core;
-
-import java.io.IOException;
-import java.net.URL;
-import java.security.*;
-import java.util.Enumeration;
-import org.eclipse.osgi.framework.adaptor.*;
-import org.eclipse.osgi.framework.debug.Debug;
-
-/**
- * The AbstractClassLoader provides some basic functionality that all
- * BundleClassLoaders must provide. It properly delegates resource and
- * class lookups to a parent classloader and the to a ClassLoaderDelegate.
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.1
- */
-public abstract class AbstractClassLoader extends ClassLoader implements BundleClassLoader {
- /**
- * The delegate used to get classes and resources from. The delegate
- * must always be queried first before the local ClassLoader is searched for
- * a class or resource.
- */
- protected ClassLoaderDelegate delegate;
-
- /**
- * The host ProtectionDomain to use to define classes.
- */
- protected ProtectionDomain hostdomain;
-
- /**
- * The host classpath entries for this classloader
- */
- protected String[] hostclasspath;
-
- /**
- * BundleClassLoader constructor.
- * @param delegate The ClassLoaderDelegate for this bundle.
- * @param domain The ProtectionDomain for this bundle.
- * @param parent The parent classloader to use. Must not be null.
- * @param classpath The classpath entries to use for the host.
- */
- public AbstractClassLoader(ClassLoaderDelegate delegate, ProtectionDomain domain, String[] classpath, ClassLoader parent) {
- super(parent);
- this.delegate = delegate;
- this.hostdomain = domain;
- this.hostclasspath = classpath;
- }
-
- /**
- * Loads a class for the bundle. First delegate.findClass(name) is called.
- * The delegate will query the system class loader, bundle imports, bundle
- * local classes, bundle hosts and fragments. The delegate will call
- * BundleClassLoader.findLocalClass(name) to find a class local to this
- * bundle.
- * @param name the name of the class to load.
- * @param resolve indicates whether to resolve the loaded class or not.
- * @return The Class object.
- * @throws ClassNotFoundException if the class is not found.
- */
- protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
- if (Debug.DEBUG && Debug.DEBUG_LOADER)
- Debug.println("BundleClassLoader[" + delegate + "].loadClass(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
- try {
- // Just ask the delegate. This could result in findLocalClass(name) being called.
- Class clazz = delegate.findClass(name);
- // resolve the class if asked to.
- if (resolve)
- resolveClass(clazz);
- return (clazz);
- } catch (Error e) {
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println("BundleClassLoader[" + delegate + "].loadClass(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- Debug.printStackTrace(e);
- }
- throw e;
- } catch (ClassNotFoundException e) {
- // If the class is not found do not try to look for it locally.
- // The delegate would have already done that for us.
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println("BundleClassLoader[" + delegate + "].loadClass(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- Debug.printStackTrace(e);
- }
- throw e;
- }
- }
-
- /**
- * Finds a class local to this bundle. The bundle class path is used
- * to search for the class. The delegate must not be used. This method
- * is abstract to force extending classes to implement this method instead
- * of using the ClassLoader.findClass(String) method.
- * @param name The classname of the class to find
- * @return The Class object.
- * @throws ClassNotFoundException if the class is not found.
- */
- abstract protected Class findClass(String name) throws ClassNotFoundException;
-
- /**
- * Gets a resource for the bundle. First delegate.findResource(name) is
- * called. The delegate will query the system class loader, bundle imports,
- * bundle local resources, bundle hosts and fragments. The delegate will
- * call BundleClassLoader.findLocalResource(name) to find a resource local
- * to this bundle.
- * @param name The resource path to get.
- * @return The URL of the resource or null if it does not exist.
- */
- public URL getResource(String name) {
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println("BundleClassLoader[" + delegate + "].getResource(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- URL url = delegate.findResource(name);
- if (url != null)
- return (url);
-
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println("BundleClassLoader[" + delegate + "].getResource(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- return (null);
- }
-
- /**
- * Finds a resource local to this bundle. Simply calls
- * findResourceImpl(name) to find the resource.
- * @param name The resource path to find.
- * @return The URL of the resource or null if it does not exist.
- */
- abstract protected URL findResource(String name);
-
- /**
- * Finds all resources with the specified name. This method must call
- * delegate.findResources(name) to find all the resources.
- * @param name The resource path to find.
- * @return An Enumeration of all resources found or null if the resource.
- * @throws IOException
- */
- protected Enumeration findResources(String name) throws IOException {
- return (delegate.findResources(name));
- }
-
- /**
- * Finds a library for this bundle. Simply calls
- * delegate.findLibrary(libname) to find the library.
- * @param libname The library to find.
- * @return The URL of the resource or null if it does not exist.
- */
- protected String findLibrary(String libname) {
- return delegate.findLibrary(libname);
- }
-
- /**
- * Finds a local resource in the BundleClassLoader without
- * consulting the delegate.
- * @param resource the resource path to find.
- * @return a URL to the resource or null if the resource does not exist.
- */
- public URL findLocalResource(String resource) {
- return findResource(resource);
- }
-
- /**
- * Finds a local class in the BundleClassLoader without
- * consulting the delegate.
- * @param classname the classname to find.
- * @return The class object found.
- * @throws ClassNotFoundException if the classname does not exist locally.
- */
- public Class findLocalClass(String classname) throws ClassNotFoundException {
- return findClass(classname);
- }
-
- /**
- * Returns a local entry for the specified path
- * @param path the entry path
- * @return a bundle entry for the specified path or <code>null</code> if the
- * path does not exist
- */
- // TODO should rename to findLocalEntry ??
- abstract public Object findLocalObject(String path);
-
- /**
- * Returns an Enumeration of local entries for the specified path. The returned
- * Enumeration is ordered using the correct local search order of the classpath for
- * this classloader.
- * @param path the entry path
- * @return an enumeration of entries for the specified path or <code>null</code> if
- * the path does not exist.
- */
- abstract public Enumeration findLocalObjects(String path);
-
- /**
- * @see BundleClassLoader#getDelegate()
- */
- public ClassLoaderDelegate getDelegate() {
- return delegate;
- }
-
- /**
- * @see BundleClassLoader#close()
- */
- public void close() {
- // do nothing
- }
-
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractFrameworkAdaptor.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractFrameworkAdaptor.java
deleted file mode 100644
index 33cc5c018..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AbstractFrameworkAdaptor.java
+++ /dev/null
@@ -1,1554 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2006 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.adaptor.core;
-
-import java.io.*;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.*;
-import org.eclipse.osgi.framework.adaptor.*;
-import org.eclipse.osgi.framework.debug.Debug;
-import org.eclipse.osgi.framework.internal.core.*;
-import org.eclipse.osgi.framework.internal.core.Constants;
-import org.eclipse.osgi.framework.log.FrameworkLog;
-import org.eclipse.osgi.framework.util.Headers;
-import org.eclipse.osgi.service.resolver.*;
-import org.eclipse.osgi.util.ManifestElement;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.*;
-
-/**
- * An abstract FrameworkAdaptor class that has default implementations that most
- * FrameworkAdaptor implementations can use.
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.1
- */
-public abstract class AbstractFrameworkAdaptor implements FrameworkAdaptor {
- /**
- * System property used to set the parent classloader type (boot is the default)
- */
- public static final String PROP_PARENT_CLASSLOADER = "osgi.parentClassloader"; //$NON-NLS-1$
- /**
- * System property used to specify the list of framework extension bundles
- */
- public static final String PROP_FRAMEWORK_EXTENSIONS = "osgi.framework.extensions"; //$NON-NLS-1$
- /**
- * System property used to specify the bundle singing support class name
- */
- public static final String PROP_SIGNINGSUPPORT = "osgi.bundlesigning.support"; //$NON-NLS-1$
- /**
- * A parent classloader type that specifies the application classloader
- */
- public static final String PARENT_CLASSLOADER_APP = "app"; //$NON-NLS-1$
- /**
- * A parent classloader type that specifies the extension classlaoder
- */
- public static final String PARENT_CLASSLOADER_EXT = "ext"; //$NON-NLS-1$
- /**
- * A parent classloader type that specifies the boot classlaoder
- */
- public static final String PARENT_CLASSLOADER_BOOT = "boot"; //$NON-NLS-1$
- /**
- * A parent classloader type that specifies the framework classlaoder
- */
- public static final String PARENT_CLASSLOADER_FWK = "fwk"; //$NON-NLS-1$
- /**
- * The bundle file name used to store bundles into the bundle storage area
- */
- public static final String BUNDLEFILE_NAME = "bundlefile"; //$NON-NLS-1$
-
- /**
- * flag to indicate a framework extension is being intialized
- */
- public static final byte EXTENSION_INITIALIZE = 0x01;
- /**
- * flag to indicate a framework extension is being installed
- */
- public static final byte EXTENSION_INSTALLED = 0x02;
- /**
- * flag to indicate a framework extension is being uninstalled
- */
- public static final byte EXTENSION_UNINSTALLED = 0x04;
- /**
- * flag to indicate a framework extension is being updated
- */
- public static final byte EXTENSION_UPDATED = 0x08;
-
- /** Name of the Adaptor manifest file */
- protected final String ADAPTOR_MANIFEST = "ADAPTOR.MF"; //$NON-NLS-1$
-
- /**
- * The default bundle signing support class name
- */
- protected final String DEFAULT_SIGNEDBUNDLE_SUPPORT = "org.eclipse.osgi.framework.pkcs7verify.SignedBundleSupportImpl"; //$NON-NLS-1$
-
- /**
- * The EventPublisher for the FrameworkAdaptor
- */
- protected EventPublisher eventPublisher;
-
- /**
- * The ServiceRegistry object for this FrameworkAdaptor.
- */
- protected ServiceRegistry serviceRegistry;
-
- /**
- * The Properties object for this FrameworkAdaptor
- */
- protected Properties properties;
-
- /**
- * The System Bundle's BundleContext.
- */
- protected BundleContext context;
-
- /**
- * The initial bundle start level.
- */
- protected int initialBundleStartLevel = 1;
-
- /** This adaptor's manifest file */
- protected Headers manifest = null;
-
- /**
- * Indicates the Framework is stopoing;
- * set to true when frameworkStopping(BundleContext) is called
- */
- protected boolean stopping = false;
-
- /**
- * The BundleClassLoader parent to use when creating BundleClassLoaders.
- * The behavior of the ParentClassLoader will load classes
- * from the boot strap classloader.
- */
- protected static ClassLoader bundleClassLoaderParent;
- /**
- * next available bundle id
- */
- protected long nextId = 1;
- /**
- * The State Manager
- */
- protected StateManager stateManager;
- /**
- * directory containing installed bundles
- */
- protected File bundleStoreRootDir;
-
- /**
- * The adaptor element factory
- */
- protected AdaptorElementFactory elementFactory;
-
- static {
- // check property for specified parent
- String type = FrameworkProperties.getProperty(PROP_PARENT_CLASSLOADER, PARENT_CLASSLOADER_BOOT);
- if (PARENT_CLASSLOADER_FWK.equalsIgnoreCase(type))
- bundleClassLoaderParent = FrameworkAdaptor.class.getClassLoader();
- else if (PARENT_CLASSLOADER_APP.equalsIgnoreCase(type))
- bundleClassLoaderParent = ClassLoader.getSystemClassLoader();
- else if (PARENT_CLASSLOADER_EXT.equalsIgnoreCase(type)) {
- ClassLoader appCL = ClassLoader.getSystemClassLoader();
- if (appCL != null)
- bundleClassLoaderParent = appCL.getParent();
- }
-
- // default to boot classloader
- if (bundleClassLoaderParent == null)
- bundleClassLoaderParent = new ParentClassLoader();
- }
-
- /**
- * The add URL method used to support framework extensions
- */
- protected Method addURLMethod;
-
- /**
- * The list of configured framework extensions
- */
- protected String[] configuredExtensions;
-
- /**
- * Indicates if signed bundles are supported
- */
- protected boolean supportSignedBundles = true;
- /**
- * The SingedBundleSupport object. This is set if signed bundles are supported
- */
- protected SignedBundleSupport signedBundleSupport = null;
-
- /**
- * Constructor for DefaultAdaptor. This constructor parses the arguments passed
- * and remembers them for later when initialize is called.
- * <p>No blank spaces should be used in the arguments to the DefaultAdaptor.
- * The options that DefaultAdaptor recognizes and handles are:
- * <ul>
- * <li><b>bundledir=<i>directory name</i></b>If a directory name is specified, the adaptor should initialize
- * to store bundles in that directory. This arg should be enclosed in "" if it contains the ":"
- * character (example "bundledir=c:\mydir").
- * <li><b>reset</b>Resets the bundle storage by deleting the bundledir
- * </ul>
- * Any other arguments are ignored.
- *
- * @param args An array of strings containing arguments.
- * This object cannot be used until initialize is called.
- *
- */
- public AbstractFrameworkAdaptor(String[] args) {
- ClassLoader fwloader = AbstractFrameworkAdaptor.class.getClassLoader();
- if (fwloader != null)
- addURLMethod = findaddURLMethod(fwloader.getClass());
- if (args != null) {
- for (int i = 0; i < args.length; i++) {
- String arg = args[i];
- if (arg.equalsIgnoreCase("reset")) { //$NON-NLS-1$
- reset = true;
- } else if (arg.indexOf("=") != -1) { //$NON-NLS-1$
- StringTokenizer tok = new StringTokenizer(args[i], "="); //$NON-NLS-1$
- if (tok.countTokens() == 2) {
- String key = tok.nextToken();
- if (key.equalsIgnoreCase("bundledir")) { //$NON-NLS-1$
- // save file name for initializeStorage to use
- bundleStore = tok.nextToken();
- }
- }
- }
- }
- }
- }
-
- /**
- * @see FrameworkAdaptor#initialize(EventPublisher)
- */
- public void initialize(EventPublisher eventPublisher) {
- this.eventPublisher = eventPublisher;
- serviceRegistry = new ServiceRegistryImpl();
- ((ServiceRegistryImpl) serviceRegistry).initialize();
- loadProperties();
- readAdaptorManifest();
- initBundleStoreRootDir();
- // need to create the FrameworkLog very early
- frameworkLog = createFrameworkLog();
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#getProperties()
- */
- public Properties getProperties() {
- return properties;
- }
-
- /**
- * Returns the AdaptorElementFactory for this Adaptor. This allows
- * extending adaptors to control how BundleData and BundleClassLoader
- * objects are created.
- * @return the AdaptorElementFactory for this Adapotr.
- */
- public abstract AdaptorElementFactory getElementFactory();
-
- /**
- * Saves the next bundle id to persist storage
- * @param value the next bundle id
- * @throws IOException
- */
- protected abstract void persistNextBundleID(long value) throws IOException;
-
- /**
- * @see FrameworkAdaptor#getFrameworkLog()
- */
- public FrameworkLog getFrameworkLog() {
- if (frameworkLog == null)
- frameworkLog = createFrameworkLog();
- return frameworkLog;
- }
-
- /**
- * @see FrameworkAdaptor#getState()
- */
- public State getState() {
- return stateManager.getSystemState();
- }
-
- /**
- * @see FrameworkAdaptor#getPlatformAdmin()
- */
- public PlatformAdmin getPlatformAdmin() {
- return stateManager;
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#mapLocationToURLConnection(String)
- */
- public URLConnection mapLocationToURLConnection(String location) throws BundleException {
- try {
- return (new URL(location).openConnection());
- } catch (IOException e) {
- throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_URL_CREATE_EXCEPTION, location), e);
- }
- }
-
- /**
- * Always returns -1 to indicate that this operation is not supported by this
- * FrameworkAdaptor. Extending classes should override this method if
- * they support this operation.
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#getTotalFreeSpace()
- */
- public long getTotalFreeSpace() throws IOException {
- return -1;
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#getServiceRegistry()
- */
- public org.eclipse.osgi.framework.adaptor.ServiceRegistry getServiceRegistry() {
- return serviceRegistry;
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#frameworkStart(org.osgi.framework.BundleContext)
- */
- public void frameworkStart(BundleContext context) throws BundleException {
- this.stopping = false;
- this.context = context;
- BundleResourceHandler.setContext(context);
- if (frameworkLog == null)
- frameworkLog = createFrameworkLog();
- if (stateManager == null)
- stateManager = createStateManager();
- State state = stateManager.getSystemState();
- checkSystemState(state);
- BundleDescription systemBundle = state.getBundle(0);
- if (systemBundle == null || !systemBundle.isResolved())
- // this would be a bug in the framework
- throw new IllegalStateException();
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#frameworkStop(org.osgi.framework.BundleContext)
- */
- public void frameworkStop(BundleContext context) throws BundleException {
- shutdownStateManager();
- this.context = null;
- BundleResourceHandler.setContext(null);
- frameworkLog.close();
- frameworkLog = null;
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#frameworkStopping(BundleContext)
- */
- public void frameworkStopping(BundleContext context) {
- this.stopping = true;
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#getExportPackages()
- */
- public String getExportPackages() {
- if (manifest == null)
- return null;
- return (String) manifest.get(Constants.EXPORT_PACKAGE);
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#getExportServices()
- */
- public String getExportServices() {
- if (manifest == null)
- return null;
- return (String) manifest.get(Constants.EXPORT_SERVICE);
- }
-
- /**
- * @see FrameworkAdaptor#getProvidePackages()
- */
- public String getProvidePackages() {
- if (manifest == null)
- return null;
- return (String) manifest.get(Constants.PROVIDE_PACKAGE);
- }
-
- /**
- * Returns the EventPublisher for this FrameworkAdaptor.
- * @return The EventPublisher.
- */
- public EventPublisher getEventPublisher() {
- return eventPublisher;
- }
-
- /**
- * Indicates if the framework is currently stopping
- * @return true if the framework is currently stopping
- */
- public boolean isStopping() {
- return stopping;
- }
-
- /**
- * @see FrameworkAdaptor#getInitialBundleStartLevel()
- */
- public int getInitialBundleStartLevel() {
- return initialBundleStartLevel;
- }
-
- /**
- * @see FrameworkAdaptor#setInitialBundleStartLevel(int)
- */
- public void setInitialBundleStartLevel(int value) {
- initialBundleStartLevel = value;
- }
-
- /**
- * @see FrameworkAdaptor#getBundleWatcher()
- */
- public BundleWatcher getBundleWatcher() {
- return null;
- }
-
- /**
- * The FrameworkLog for the adaptor
- */
- protected FrameworkLog frameworkLog;
-
- public static final String BUNDLE_STORE = "osgi.bundlestore"; //$NON-NLS-1$
-
- /**
- * This method locates and reads the osgi.properties file.
- * If the system property <i>org.eclipse.osgi.framework.internal.core.properties</i> is specifed, its value
- * will be used as the name of the file instead of
- * <tt>osgi.properties</tt>. There are 3 places to look for these properties. These
- * 3 places are searched in the following order, stopping when the properties are found.
- *
- * <ol>
- * <li>Look for a file in the file system
- * <li>Look for a resource in the FrameworkAdaptor's package
- * </ol>
- */
- protected void loadProperties() {
- properties = new Properties();
-
- String resource = FrameworkProperties.getProperty(Constants.OSGI_PROPERTIES, Constants.DEFAULT_OSGI_PROPERTIES);
-
- try {
- InputStream in = null;
- File file = new File(resource);
- if (file.exists()) {
- in = new FileInputStream(file);
- }
-
- if (in == null) {
- in = getClass().getResourceAsStream(resource);
- }
-
- if (in != null) {
- try {
- properties.load(new BufferedInputStream(in));
- } finally {
- try {
- in.close();
- } catch (IOException ee) {
- }
- }
- } else {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL)
- Debug.println("Skipping osgi.properties: " + resource); //$NON-NLS-1$
- }
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to load osgi.properties: " + e.getMessage()); //$NON-NLS-1$
- }
- }
-
- // need to set some OSGi Framework properties that only the adaptor would know about
- if (addURLMethod != null)
- properties.put(Constants.SUPPORTS_FRAMEWORK_EXTENSION, "true"); //$NON-NLS-1$
- }
-
- /**
- * Return the next valid, unused bundle id.
- *
- * @return Next valid, unused bundle id.
- * @throws IOException If there are no more unused bundle ids.
- */
- protected synchronized long getNextBundleId() throws IOException {
- while (nextId < Long.MAX_VALUE) {
- long id = nextId;
- nextId++;
-
- File bundleDir = new File(getBundleStoreRootDir(), String.valueOf(id));
- if (bundleDir.exists()) {
- continue;
- }
- persistNextBundleID(id);
- return (id);
- }
-
- throw new IOException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION);
- }
-
- /**
- * Initializes the root bundle data directory
- *
- */
- protected void initDataRootDir() {
- dataRootDir = getBundleStoreRootDir();
- }
-
- /**
- * Reads and initializes the adaptor BundleManifest object. The
- * BundleManifest is used by the getExportPackages() and getExportServices()
- * methods of the adpator.
- */
- protected void readAdaptorManifest() {
- InputStream in = null;
- // walk up the class hierarchy until we find the ADAPTOR_MANIFEST.
- Class adaptorClazz = getClass();
- while (in == null && AbstractFrameworkAdaptor.class.isAssignableFrom(adaptorClazz)) {
- in = adaptorClazz.getResourceAsStream(ADAPTOR_MANIFEST);
- adaptorClazz = adaptorClazz.getSuperclass();
- }
-
- if (in == null) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to find adaptor bundle manifest " + ADAPTOR_MANIFEST); //$NON-NLS-1$
- }
- manifest = new Headers(new Properties());
- return;
- }
- try {
- manifest = Headers.parseManifest(in);
- } catch (BundleException e) {
- Debug.println("Unable to read adaptor bundle manifest " + ADAPTOR_MANIFEST); //$NON-NLS-1$
- }
- }
-
- /**
- * Creates a framework log
- * @return a framework log
- */
- abstract protected FrameworkLog createFrameworkLog();
-
- /**
- * @see FrameworkAdaptor#createSystemBundleData()
- */
- public BundleData createSystemBundleData() throws BundleException {
- return new SystemBundleData(this);
- }
-
- /**
- * Does a recursive copy of one directory to another.
- * @param inDir input directory to copy.
- * @param outDir output directory to copy to.
- * @throws IOException if any error occurs during the copy.
- */
- public static void copyDir(File inDir, File outDir) throws IOException {
- String[] files = inDir.list();
- if (files != null && files.length > 0) {
- outDir.mkdir();
- for (int i = 0; i < files.length; i++) {
- File inFile = new File(inDir, files[i]);
- File outFile = new File(outDir, files[i]);
- if (inFile.isDirectory()) {
- copyDir(inFile, outFile);
- } else {
- InputStream in = new FileInputStream(inFile);
- readFile(in, outFile);
- }
- }
- }
- }
-
- /**
- * Read a file from an InputStream and write it to the file system.
- *
- * @param in InputStream from which to read.
- * @param file output file to create.
- * @exception IOException
- */
- public static void readFile(InputStream in, File file) throws IOException {
- FileOutputStream fos = null;
- try {
- fos = new FileOutputStream(file);
-
- byte buffer[] = new byte[1024];
- int count;
- while ((count = in.read(buffer, 0, buffer.length)) > 0) {
- fos.write(buffer, 0, count);
- }
-
- fos.close();
- fos = null;
-
- in.close();
- in = null;
- } catch (IOException e) {
- // close open streams
- if (fos != null) {
- try {
- fos.close();
- } catch (IOException ee) {
- }
- }
-
- if (in != null) {
- try {
- in.close();
- } catch (IOException ee) {
- }
- }
-
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to read file"); //$NON-NLS-1$
- Debug.printStackTrace(e);
- }
-
- throw e;
- }
- }
-
- private static Method findaddURLMethod(Class clazz) {
- if (clazz == null)
- return null; // ends the recursion when getSuperClass returns null
- try {
- Method result = clazz.getDeclaredMethod("addURL", new Class[] {URL.class}); //$NON-NLS-1$
- result.setAccessible(true);
- return result;
- } catch (NoSuchMethodException e) {
- // do nothing look in super class below
- } catch (SecurityException e) {
- // if we do not have the permissions then we will not find the method
- }
- return findaddURLMethod(clazz.getSuperclass());
- }
-
- /**
- * @see FrameworkAdaptor#getBundleClassLoaderParent()
- */
- public ClassLoader getBundleClassLoaderParent() {
- return bundleClassLoaderParent;
- }
-
- /**
- * Processes an extension bundle
- * @param bundleData the extension bundle data
- * @param type the type of extension bundle
- * @throws BundleException on any errors or if the extension bundle type is not supported
- */
- protected void processExtension(BundleData bundleData, byte type) throws BundleException {
- if ((bundleData.getType() & BundleData.TYPE_FRAMEWORK_EXTENSION) != 0) {
- validateExtension(bundleData);
- processFrameworkExtension(bundleData, type);
- } else if ((bundleData.getType() & BundleData.TYPE_BOOTCLASSPATH_EXTENSION) != 0) {
- validateExtension(bundleData);
- processBootExtension(bundleData, type);
- }
- }
-
- /**
- * Validates the extension bundle metadata
- * @param bundleData the extension bundle data
- * @throws BundleException if the extension bundle metadata is invalid
- */
- protected void validateExtension(BundleData bundleData) throws BundleException {
- Dictionary extensionManifest = bundleData.getManifest();
- if (extensionManifest.get(Constants.IMPORT_PACKAGE) != null)
- throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_EXTENSION_IMPORT_ERROR, bundleData.getLocation()));
- if (extensionManifest.get(Constants.REQUIRE_BUNDLE) != null)
- throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_EXTENSION_REQUIRE_ERROR, bundleData.getLocation()));
- if (extensionManifest.get(Constants.BUNDLE_NATIVECODE) != null)
- throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_EXTENSION_NATIVECODE_ERROR, bundleData.getLocation()));
- }
-
- /**
- * Processes a framework extension bundle
- * @param bundleData the extension bundle data
- * @param type the type of extension bundle
- * @throws BundleException on errors or if framework extensions are not supported
- */
- protected void processFrameworkExtension(BundleData bundleData, byte type) throws BundleException {
- if (addURLMethod == null)
- throw new BundleException("Framework extensions are not supported.", new UnsupportedOperationException()); //$NON-NLS-1$
- if ((type & (EXTENSION_UNINSTALLED | EXTENSION_UPDATED)) != 0)
- // if uninstalled or updated then do nothing framework must be restarted.
- return;
-
- // first make sure this BundleData is not on the pre-configured osgi.framework.extensions list
- String[] extensions = getConfiguredExtensions();
- for (int i = 0; i < extensions.length; i++)
- if (extensions[i].equals(bundleData.getSymbolicName()))
- return;
- File[] files = getExtensionFiles(bundleData);
- if (files == null)
- return;
- for (int i = 0; i < files.length; i++) {
- if (files[i] == null)
- continue;
- Throwable exceptionLog = null;
- try {
- addURLMethod.invoke(getClass().getClassLoader(), new Object[] {files[i].toURL()});
- } catch (InvocationTargetException e) {
- exceptionLog = e.getTargetException();
- } catch (Throwable t) {
- exceptionLog = t;
- } finally {
- if (exceptionLog != null)
- eventPublisher.publishFrameworkEvent(FrameworkEvent.ERROR, ((AbstractBundleData) bundleData).getBundle(), exceptionLog);
- }
- }
- }
-
- /**
- * Returns a list of configured extensions
- * @return a list of configured extensions
- */
- protected String[] getConfiguredExtensions() {
- if (configuredExtensions != null)
- return configuredExtensions;
- String prop = FrameworkProperties.getProperty(PROP_FRAMEWORK_EXTENSIONS);
- if (prop == null || prop.trim().length() == 0)
- configuredExtensions = new String[0];
- else
- configuredExtensions = ManifestElement.getArrayFromList(prop);
- return configuredExtensions;
- }
-
- /**
- * Processes a boot extension bundle
- * @param bundleData the extension bundle data
- * @param type the type of extension bundle
- * @throws BundleException on errors or if boot extensions are not supported
- */
- protected void processBootExtension(BundleData bundleData, byte type) throws BundleException {
- throw new BundleException("Boot classpath extensions are not supported.", new UnsupportedOperationException()); //$NON-NLS-1$
- }
-
- /**
- * Returns a list of classpath files for an extension bundle
- * @param bundleData the bundle data for an extension bundle
- * @return a list of classpath files for an extension bundle
- */
- protected File[] getExtensionFiles(BundleData bundleData) {
- File[] files = null;
- try {
- String[] paths = bundleData.getClassPath();
- // TODO need to be smarter about dev path here
- if (FrameworkProperties.getProperty("osgi.dev") != null) { //$NON-NLS-1$
- String[] origPaths = paths;
- paths = new String[origPaths.length + 1];
- System.arraycopy(origPaths, 0, paths, 0, origPaths.length);
- paths[paths.length - 1] = "bin"; //$NON-NLS-1$
- }
- files = ((AbstractBundleData) bundleData).getClasspathFiles(paths);
- } catch (BundleException e) {
- eventPublisher.publishFrameworkEvent(FrameworkEvent.ERROR, ((AbstractBundleData) bundleData).getBundle(), e);
- }
- return files;
- }
-
- /**
- * @see FrameworkAdaptor#handleRuntimeError(Throwable)
- */
- public void handleRuntimeError(Throwable error) {
- // do nothing by default.
- }
-
- /**
- * Returns the root data directory
- * @return the root data directory
- */
- public File getDataRootDir() {
- if (dataRootDir == null)
- initDataRootDir();
- return dataRootDir;
- }
-
- /**
- * Creates a BundleFile object from a File object and a BundleData
- * object. This implementation checks to see if the basefile is
- * a directory or a regular file and creates the proper BundleFile
- * type accordingly. If the file is a regular file this implementation
- * assumes that the file is a zip file.
- * @param basefile the base File object.
- * @param bundledata the BundleData object that BundleFile is associated with.
- * @return A new BundleFile object
- * @throws IOException if an error occurred creating the BundleFile object.
- */
- public BundleFile createBundleFile(File basefile, BundleData bundledata) throws IOException {
- if (basefile.isDirectory())
- return new BundleFile.DirBundleFile(basefile);
- return new BundleFile.ZipBundleFile(basefile, bundledata);
- }
-
- /**
- * Creates a base bundle file for a bundle
- * @param basefile the base file object for the bundle
- * @param bundledata the bundle data for the bundle
- * @return a base bundle file for a bundle
- * @throws IOException
- */
- public BundleFile createBaseBundleFile(File basefile, BundleData bundledata) throws IOException {
- BundleFile base = createBundleFile(basefile, bundledata);
- if (System.getSecurityManager() == null || !supportSignedBundles)
- return base;
- SignedBundleSupport support = getSignedBundleSupport();
- if (support == null)
- return base;
- SignedBundle signedBundle = support.createSignedBundle();
- signedBundle.setBundleFile(base);
- return signedBundle;
- }
-
- /**
- * @see FrameworkAdaptor#matchDNChain(String, String[])
- */
- public boolean matchDNChain(String pattern, String[] dnChain) {
- SignedBundleSupport support = getSignedBundleSupport();
- if (support != null)
- return support.matchDNChain(pattern, dnChain);
- return false;
- }
-
- /**
- * Returns the SignedBundleSupport object. If signed bundles are not
- * supported then <code>null</code> is returned.
- * @return the SignedBundleSupport object or <code>null</code> if signed bundles
- * are not supported.
- */
- protected SignedBundleSupport getSignedBundleSupport() {
- if (System.getSecurityManager() == null || !supportSignedBundles)
- return null;
- try {
- if (signedBundleSupport == null) {
- String clazzName = FrameworkProperties.getProperty(PROP_SIGNINGSUPPORT, DEFAULT_SIGNEDBUNDLE_SUPPORT);
- Class clazz = Class.forName(clazzName);
- signedBundleSupport = (SignedBundleSupport) clazz.newInstance();
- }
- return signedBundleSupport;
- } catch (ClassNotFoundException e) {
- supportSignedBundles = false;
- } catch (IllegalAccessException e) {
- supportSignedBundles = false;
- } catch (InstantiationException e) {
- supportSignedBundles = false;
- }
- return null;
- }
-
- /**
- * @see FrameworkAdaptor#installBundle(String, URLConnection)
- */
- public BundleOperation installBundle(final String location, final URLConnection source) {
- return (new BundleOperation() {
- private AbstractBundleData data;
-
- /**
- * Begin the operation on the bundle (install, update, uninstall).
- *
- * @return BundleData object for the target bundle.
- * @throws BundleException If a failure occured modifiying peristent storage.
- */
- public org.eclipse.osgi.framework.adaptor.BundleData begin() throws BundleException {
- long id;
-
- try {
- /*
- * Open InputStream first to trigger prereq installs, if any,
- * before allocating bundle id.
- */
- InputStream in = source.getInputStream();
- URL sourceURL = source.getURL();
- String protocol = sourceURL == null ? null : sourceURL.getProtocol();
- try {
- try {
- id = getNextBundleId();
- } catch (IOException e) {
- throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e);
- }
- data = getElementFactory().createBundleData(AbstractFrameworkAdaptor.this, id);
- data.setLastModified(System.currentTimeMillis());
- data.setLocation(location);
- data.setStartLevel(getInitialBundleStartLevel());
-
- if (in instanceof ReferenceInputStream) {
- URL reference = ((ReferenceInputStream) in).getReference();
-
- if (!"file".equals(reference.getProtocol())) { //$NON-NLS-1$
- throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_URL_CREATE_EXCEPTION, reference));
- }
-
- data.setReference(true);
- data.setFileName(reference.getPath());
- data.initializeNewBundle();
- } else {
- File genDir = data.createGenerationDir();
- if (!genDir.exists()) {
- throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, genDir.getPath()));
- }
-
- String fileName = BUNDLEFILE_NAME;
- File outFile = new File(genDir, fileName);
- if ("file".equals(protocol)) { //$NON-NLS-1$
- File inFile = new File(source.getURL().getPath());
- if (inFile.isDirectory()) {
- copyDir(inFile, outFile);
- } else {
- readFile(in, outFile);
- }
- } else {
- readFile(in, outFile);
- }
- data.setReference(false);
- data.setFileName(fileName);
- data.initializeNewBundle();
- }
- } finally {
- try {
- in.close();
- } catch (IOException e) {
- }
- }
- } catch (IOException ioe) {
- throw new BundleException(AdaptorMsg.BUNDLE_READ_EXCEPTION, ioe);
- }
-
- return (data);
- }
-
- public void undo() {
- if (data != null) {
- try {
- data.close();
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to close " + data + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
- }
-
- if (data != null) {
- File bundleDir = data.getBundleStoreDir();
-
- if (!rm(bundleDir)) {
- /* mark this bundle to be deleted to ensure it is fully cleaned up
- * on next restart.
- */
- File delete = new File(bundleDir, ".delete"); //$NON-NLS-1$
-
- if (!delete.exists()) {
- try {
- /* create .delete */
- FileOutputStream out = new FileOutputStream(delete);
- out.close();
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
- }
- }
- }
- }
-
- public void commit(boolean postpone) throws BundleException {
- processExtension(data, EXTENSION_INSTALLED);
- try {
- data.save();
- } catch (IOException e) {
- throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e);
- }
- updateState(data, BundleEvent.INSTALLED);
- }
-
- });
- }
-
- /**
- * This function performs the equivalent of "rm -r" on a file or directory.
- *
- * @param file file or directory to delete
- * @return false is the specified files still exists, true otherwise.
- */
- protected boolean rm(File file) {
- if (file.exists()) {
- if (file.isDirectory()) {
- String list[] = file.list();
- if (list != null) {
- int len = list.length;
- for (int i = 0; i < len; i++) {
- // we are doing a lot of garbage collecting here
- rm(new File(file, list[i]));
- }
- }
- }
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- if (file.isDirectory()) {
- Debug.println("rmdir " + file.getPath()); //$NON-NLS-1$
- } else {
- Debug.println("rm " + file.getPath()); //$NON-NLS-1$
- }
- }
-
- boolean success = file.delete();
-
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- if (!success) {
- Debug.println(" rm failed!!"); //$NON-NLS-1$
- }
- }
-
- return (success);
- }
- return (true);
- }
-
- /**
- * Shutdown the StateManager for the adaptor. This should persist the state
- * for reading when createStateManager is called.
- */
- protected void shutdownStateManager() {
- try {
- if (canWrite() && (getBundleStoreRootDir().exists() || getBundleStoreRootDir().mkdirs()))
- stateManager.shutdown(new File(getBundleStoreRootDir(), ".state"), new File(getBundleStoreRootDir(), ".lazy")); //$NON-NLS-1$//$NON-NLS-2$
- } catch (IOException e) {
- frameworkLog.log(new FrameworkEvent(FrameworkEvent.ERROR, context.getBundle(), e));
- } finally {
- stateManager = null;
- }
- }
-
- /**
- * Returns the bundle store root directory
- * @return the bundle store root directory
- */
- public File getBundleStoreRootDir() {
- return bundleStoreRootDir;
- }
-
- /**
- * String containing bundle store root dir
- */
- protected String bundleStore = null;
- /**
- * Dictionary containing permission data
- */
- protected PermissionStorage permissionStore;
- /**
- * inidicates that the bundle storage should be reset
- */
- protected boolean reset = false;
- /**
- * directory containing data directories for installed bundles
- */
- protected File dataRootDir;
- /**
- * The name of the bundle data directory
- */
- public static final String DATA_DIR_NAME = "data";//$NON-NLS-1$
- /**
- * Indicates that the state has become invalid as a result of
- * installing/updating/uninstalling a bundle before the state mananger is
- * created
- */
- protected boolean invalidState = false;
-
- /**
- * @see FrameworkAdaptor#updateBundle(BundleData, URLConnection)
- */
- public BundleOperation updateBundle(final org.eclipse.osgi.framework.adaptor.BundleData bundledata, final URLConnection source) {
- return (new BundleOperation() {
- private AbstractBundleData data;
- private AbstractBundleData newData;
-
- /**
- * Perform the change to persistent storage.
- *
- * @return Bundle object for the target bundle.
- */
- public org.eclipse.osgi.framework.adaptor.BundleData begin() throws BundleException {
- this.data = (AbstractBundleData) bundledata;
- try {
- InputStream in = source.getInputStream();
- URL sourceURL = source.getURL();
- String protocol = sourceURL == null ? null : sourceURL.getProtocol();
- try {
- if (in instanceof ReferenceInputStream) {
- ReferenceInputStream refIn = (ReferenceInputStream) in;
- URL reference = (refIn).getReference();
- if (!"file".equals(reference.getProtocol())) { //$NON-NLS-1$
- throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_URL_CREATE_EXCEPTION, reference));
- }
- // check to make sure we are not just trying to update to the same
- // directory reference. This would be a no-op.
- String path = reference.getPath();
- if (path.equals(data.getFileName())) {
- throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_SAME_REF_UPDATE, reference));
- }
- try {
- newData = data.nextGeneration(reference.getPath());
- } catch (IOException e) {
- throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e);
- }
- File bundleGenerationDir = newData.createGenerationDir();
- if (!bundleGenerationDir.exists()) {
- throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, bundleGenerationDir.getPath()));
- }
- newData.createBaseBundleFile();
- } else {
- try {
- newData = data.nextGeneration(null);
- } catch (IOException e) {
- throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e);
- }
- File bundleGenerationDir = newData.createGenerationDir();
- if (!bundleGenerationDir.exists()) {
- throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, bundleGenerationDir.getPath()));
- }
- File outFile = newData.getBaseFile();
- if ("file".equals(protocol)) { //$NON-NLS-1$
- File inFile = new File(source.getURL().getPath());
- if (inFile.isDirectory()) {
- copyDir(inFile, outFile);
- } else {
- readFile(in, outFile);
- }
- } else {
- readFile(in, outFile);
- }
- newData.createBaseBundleFile();
- }
- } finally {
- try {
- in.close();
- } catch (IOException ee) {
- }
- }
- newData.loadFromManifest();
- } catch (IOException e) {
- throw new BundleException(AdaptorMsg.BUNDLE_READ_EXCEPTION, e);
- }
-
- return (newData);
- }
-
- /**
- * Commit the change to persistent storage.
- *
- * @param postpone If true, the bundle's persistent
- * storage cannot be immediately reclaimed.
- * @throws BundleException If a failure occured modifiying peristent storage.
- */
-
- public void commit(boolean postpone) throws BundleException {
- processExtension(data, EXTENSION_UNINSTALLED); // remove the old extension
- processExtension(newData, EXTENSION_UPDATED); // update to the new one
- try {
- newData.setLastModified(System.currentTimeMillis());
- newData.save();
- } catch (IOException e) {
- throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e);
- }
- updateState(newData, BundleEvent.UPDATED);
- File originalGenerationDir = data.createGenerationDir();
-
- if (postpone || !rm(originalGenerationDir)) {
- /* mark this bundle to be deleted to ensure it is fully cleaned up
- * on next restart.
- */
- File delete = new File(originalGenerationDir, ".delete"); //$NON-NLS-1$
-
- if (!delete.exists()) {
- try {
- /* create .delete */
- FileOutputStream out = new FileOutputStream(delete);
- out.close();
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- eventPublisher.publishFrameworkEvent(FrameworkEvent.ERROR, data.getBundle(), e);
- }
- }
- }
- }
-
- /**
- * Undo the change to persistent storage.
- *
- * @throws BundleException If a failure occured modifiying peristent storage.
- */
- public void undo() throws BundleException {
- /*if (bundleFile != null)
- {
- bundleFile.close();
- } */
-
- if (newData != null) {
- File nextGenerationDir = newData.createGenerationDir();
-
- if (!rm(nextGenerationDir)) /* delete downloaded bundle */{
- /* mark this bundle to be deleted to ensure it is fully cleaned up
- * on next restart.
- */
- File delete = new File(nextGenerationDir, ".delete"); //$NON-NLS-1$
-
- if (!delete.exists()) {
- try {
- /* create .delete */
- FileOutputStream out = new FileOutputStream(delete);
- out.close();
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
- }
- }
- }
- }
- });
- }
-
- /**
- * Iterates over the bundles in a state and removes any bundles in state that
- * do not exist in the framework
- * @param state the state to check
- */
- protected void checkSystemState(State state) {
- BundleDescription[] bundles = state.getBundles();
- if (bundles == null)
- return;
- boolean removedBundle = false;
- for (int i = 0; i < bundles.length; i++) {
- if (context.getBundle(bundles[i].getBundleId()) == null) {
- state.removeBundle(bundles[i]);
- removedBundle = true;
- }
- }
- if (removedBundle)
- state.resolve(false); // do a full resolve
- }
-
- /**
- * Creates the StateManager for the adaptor
- * @return the StateManager.
- */
- protected StateManager createStateManager() {
- stateManager = new StateManager(new File(getBundleStoreRootDir(), ".state"), new File(getBundleStoreRootDir(), ".lazy"), context); //$NON-NLS-1$ //$NON-NLS-2$
- State systemState = null;
- if (!invalidState) {
- systemState = stateManager.readSystemState();
- if (systemState != null)
- return stateManager;
- }
- systemState = stateManager.createSystemState();
- Bundle[] installedBundles = context.getBundles();
- if (installedBundles == null)
- return stateManager;
- StateObjectFactory factory = stateManager.getFactory();
- for (int i = 0; i < installedBundles.length; i++) {
- Bundle toAdd = installedBundles[i];
- try {
- Dictionary manifest = toAdd.getHeaders(""); //$NON-NLS-1$
- BundleDescription newDescription = factory.createBundleDescription(systemState, manifest, toAdd.getLocation(), toAdd.getBundleId());
- systemState.addBundle(newDescription);
- } catch (BundleException be) {
- // just ignore bundle datas with invalid manifests
- }
- }
- // we need the state resolved
- systemState.resolve();
- invalidState = false;
- return stateManager;
- }
-
- /**
- * @see FrameworkAdaptor#uninstallBundle(BundleData)
- */
- public BundleOperation uninstallBundle(final org.eclipse.osgi.framework.adaptor.BundleData bundledata) {
- return (new BundleOperation() {
- private AbstractBundleData data;
-
- /**
- * Perform the change to persistent storage.
- *
- * @return Bundle object for the target bundle.
- * @throws BundleException If a failure occured modifiying peristent storage.
- */
- public org.eclipse.osgi.framework.adaptor.BundleData begin() throws BundleException {
- this.data = (AbstractBundleData) bundledata;
- return (bundledata);
- }
-
- /**
- * Commit the change to persistent storage.
- *
- * @param postpone If true, the bundle's persistent
- * storage cannot be immediately reclaimed.
- * @throws BundleException If a failure occured modifiying peristent storage.
- */
- public void commit(boolean postpone) throws BundleException {
- File bundleDir = data.getBundleStoreDir();
-
- if (postpone || !rm(bundleDir)) {
- /* mark this bundle to be deleted to ensure it is fully cleaned up
- * on next restart.
- */
-
- File delete = new File(bundleDir, ".delete"); //$NON-NLS-1$
-
- if (!delete.exists()) {
- try {
- /* create .delete */
- FileOutputStream out = new FileOutputStream(delete);
- out.close();
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
- }
- }
-
- processExtension(data, EXTENSION_UNINSTALLED);
- data.setLastModified(System.currentTimeMillis());
- updateState(data, BundleEvent.UNINSTALLED);
- }
-
- /**
- * Undo the change to persistent storage.
- *
- * @throws BundleException If a failure occured modifiying peristent storage.
- */
- public void undo() throws BundleException {
- }
- });
- }
-
- /**
- * Init the directory to store the bundles in. Bundledir can be set in 3 different ways.
- * Priority is:
- * 1 - OSGI Launcher command line -adaptor argument
- * 2 - System property osgi.bundlestore - could be specified with -D when launching
- * 3 - osgi.properties - osgi.bundlestore property
- *
- * Bundledir will be stored back to adaptor properties which
- * the framework will copy into the System properties.
- */
- protected void initBundleStoreRootDir() {
- /* if bundleStore was not set by the constructor from the -adaptor cmd line arg */
- if (bundleStore == null) {
- /* check the system properties */
- bundleStore = FrameworkProperties.getProperty(BUNDLE_STORE);
-
- if (bundleStore == null) {
- /* check the osgi.properties file, but default to "bundles" */
- bundleStore = properties.getProperty(BUNDLE_STORE, "bundles"); //$NON-NLS-1$
- }
- }
-
- bundleStoreRootDir = new File(bundleStore);
- /* store bundleStore back into adaptor properties for others to see */
- properties.put(BUNDLE_STORE, bundleStoreRootDir.getAbsolutePath());
-
- }
-
- /**
- * Register a service object.
- * @param name the service class name
- * @param service the service object
- * @param bundle the registering bundle
- * @return the service registration object
- */
- protected ServiceRegistration register(String name, Object service, Bundle bundle) {
- Hashtable properties = new Hashtable(7);
-
- Dictionary headers = bundle.getHeaders();
-
- properties.put(Constants.SERVICE_VENDOR, headers.get(Constants.BUNDLE_VENDOR));
-
- properties.put(Constants.SERVICE_RANKING, new Integer(Integer.MAX_VALUE));
-
- properties.put(Constants.SERVICE_PID, bundle.getBundleId() + "." + service.getClass().getName()); //$NON-NLS-1$
-
- return context.registerService(name, service, properties);
- }
-
- /**
- * Initialize the persistent storage.
- *
- * <p>This method initializes the bundle persistent storage
- * area.
- * If a dir was specified in the -adaptor command line option, then it
- * is used. If not,
- * if the property
- * <i>osgi.bundlestore</i> is specified, its value
- * will be used as the name of the bundle directory
- * instead of <tt>./bundles</tt>.
- * If reset was specified on the -adaptor command line option,
- * then the storage will be cleared.
- *
- * @throws IOException If an error occurs initializing the storage.
- */
- public void initializeStorage() throws IOException {
- File bundleStore;
- // only touch the file system if reset is specified
- // we create the area on demand later if needed
- if (reset && (bundleStore = getBundleStoreRootDir()).exists()) {
- if (!canWrite() || !rm(bundleStore)) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Could not remove directory: " + bundleStore.getPath()); //$NON-NLS-1$
- }
-
- throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_REMOVE_EXCEPTION, bundleStore));
- }
- }
-
- initializeMetadata();
- }
-
- /**
- * Initialize the metadata for the adaptor
- * @throws IOException
- */
- abstract protected void initializeMetadata() throws IOException;
-
- /**
- * @see FrameworkAdaptor#getPermissionStorage()
- */
- public org.eclipse.osgi.framework.adaptor.PermissionStorage getPermissionStorage() throws IOException {
- if (permissionStore == null) {
- synchronized (this) {
- if (permissionStore == null) {
- permissionStore = new DefaultPermissionStorage(this);
- }
- }
- }
-
- return permissionStore;
- }
-
- /**
- * @see FrameworkAdaptor#compactStorage()
- */
- public void compactStorage() {
- if (canWrite())
- compact(getBundleStoreRootDir());
- }
-
- /**
- * This method cleans up storage in the specified directory and
- * any subdirectories.
- *
- * @param directory The directory to clean.
- * @see #compactStorage
- */
- private void compact(File directory) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("compact(" + directory.getPath() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- String list[] = directory.list();
- if (list == null)
- return;
-
- int len = list.length;
-
- for (int i = 0; i < len; i++) {
- if (DATA_DIR_NAME.equals(list[i])) {
- continue; /* do not examine the bundles data dir. */
- }
-
- File target = new File(directory, list[i]);
-
- /* if the file is a directory */
- if (!target.isDirectory())
- continue;
- File delete = new File(target, ".delete"); //$NON-NLS-1$
-
- /* and the directory is marked for delete */
- if (delete.exists()) {
- /* if rm fails to delete the directory *
- * and .delete was removed
- */
- if (!rm(target) && !delete.exists()) {
- try {
- /* recreate .delete */
- FileOutputStream out = new FileOutputStream(delete);
- out.close();
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
- }
- } else {
- compact(target); /* descend into directory */
- }
- }
- }
-
- /**
- * Returns the metadata file for the adaptor
- * @return the metadata file for the adaptor
- */
- protected File getMetaDataFile() {
- return new File(getBundleStoreRootDir(), ".framework"); //$NON-NLS-1$
- }
-
- /**
- * Empty parent classloader. This is used by default as the BundleClassLoader
- * parent.
- */
- protected static class ParentClassLoader extends ClassLoader {
- protected ParentClassLoader() {
- super(null);
- }
- }
-
- /**
- * Updates the state mananager with an updated/installed/uninstalled bundle
- * @param bundleData the modified bundle
- * @param type the type of modification
- * @throws BundleException
- */
- protected void updateState(BundleData bundleData, int type) throws BundleException {
- if (stateManager == null) {
- invalidState = true;
- return;
- }
- State systemState = stateManager.getSystemState();
- switch (type) {
- case BundleEvent.UPDATED :
- systemState.removeBundle(bundleData.getBundleID());
- // fall through to INSTALLED
- case BundleEvent.INSTALLED :
- BundleDescription newDescription = stateManager.getFactory().createBundleDescription(systemState, bundleData.getManifest(), bundleData.getLocation(), bundleData.getBundleID());
- systemState.addBundle(newDescription);
- break;
- case BundleEvent.UNINSTALLED :
- systemState.removeBundle(bundleData.getBundleID());
- break;
- }
- }
-
- /**
- * Whether the adaptor can make changes to the file system. Default is <code>true</code>.
- */
- public boolean canWrite() {
- return true;
- }
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AdaptorElementFactory.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AdaptorElementFactory.java
deleted file mode 100644
index a3abb5c18..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AdaptorElementFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.osgi.framework.adaptor.core;
-
-import java.io.IOException;
-import org.eclipse.osgi.framework.adaptor.BundleClassLoader;
-import org.eclipse.osgi.framework.adaptor.BundleProtectionDomain;
-import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
-
-/**
- * This interface allows extending adaptors to control how BundleData and BundleClassLoader
- * objects are created.
- * <p>
- * Clients may implement this interface.
- * </p>
- * @since 3.1
- */
-public interface AdaptorElementFactory {
- /**
- * Creates a bundle data object for a bundle
- * @param adaptor the adaptor creating the bundle data for
- * @param id the bundle ID to use for the constructed bundle data object
- * @return a bundle data object for a bundle
- * @throws IOException
- */
- public AbstractBundleData createBundleData(AbstractFrameworkAdaptor adaptor, long id) throws IOException;
-
- /**
- * Creates a bundle classloader for a bundle
- * @param delegate the classloader delegate
- * @param domain the classloader domain
- * @param bundleclasspath the classloader classapth
- * @param data the classloader bundle data
- * @return a bundle classloader for a bundle
- */
- public BundleClassLoader createClassLoader(ClassLoaderDelegate delegate, BundleProtectionDomain domain, String[] bundleclasspath, AbstractBundleData data);
-
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleEntry.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleEntry.java
deleted file mode 100644
index 926ecd1a7..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleEntry.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.adaptor.core;
-
-import java.io.*;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.zip.ZipEntry;
-
-/**
- * A BundleEntry represents one entry of a BundleFile.
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.1
- */
-public abstract class BundleEntry {
- /**
- * Return an InputStream for the entry.
- *
- * @return InputStream for the entry.
- * @throws java.io.IOException If an error occurs reading the bundle.
- */
- public abstract InputStream getInputStream() throws IOException;
-
- /**
- * Return the size of the entry (uncompressed).
- *
- * @return size of entry.
- */
- public abstract long getSize();
-
- /**
- * Return the name of the entry.
- *
- * @return name of entry.
- */
- public abstract String getName();
-
- /**
- * Get the modification time for this BundleEntry.
- * <p>If the modification time has not been set,
- * this method will return <tt>-1</tt>.
- *
- * @return last modification time.
- */
- public abstract long getTime();
-
- /**
- * Get a URL to the bundle entry that uses a common protocol (i.e. file:
- * jar: or http: etc.).
- * @return a URL to the bundle entry that uses a common protocol
- */
- public abstract URL getLocalURL();
-
- /**
- * Get a URL to the content of the bundle entry that uses the file: protocol.
- * The content of the bundle entry may be downloaded or extracted to the local
- * file system in order to create a file: URL.
- * @return a URL to the content of the bundle entry that uses the file: protocol
- */
- public abstract URL getFileURL();
-
- /**
- * Return the name of this BundleEntry by calling getName().
- *
- * @return String representation of this BundleEntry.
- */
- public String toString() {
- return (getName());
- }
-
- /**
- * A BundleEntry represented by a ZipEntry in a ZipFile. The ZipBundleEntry
- * class is used for bundles that are installed as a ZipFile on a file system.
- */
- public static class ZipBundleEntry extends BundleEntry {
- /**
- * ZipEntry for this entry.
- */
- protected ZipEntry zipEntry;
-
- /**
- * The BundleFile for this entry.
- */
- protected BundleFile bundleFile;
-
- /**
- * Constructs the BundleEntry using a ZipEntry.
- * @param bundleFile BundleFile object this entry is a member of
- * @param entry ZipEntry object of this entry
- */
- protected ZipBundleEntry(ZipEntry entry, BundleFile bundleFile) {
- this.zipEntry = entry;
- this.bundleFile = bundleFile;
- }
-
- /**
- * Return an InputStream for the entry.
- *
- * @return InputStream for the entry
- * @exception java.io.IOException
- */
- public InputStream getInputStream() throws IOException {
- return ((BundleFile.ZipBundleFile) bundleFile).getZipFile().getInputStream(zipEntry);
- }
-
- /**
- * Return size of the uncompressed entry.
- *
- * @return size of entry
- */
- public long getSize() {
- return zipEntry.getSize();
- }
-
- /**
- * Return name of the entry.
- *
- * @return name of entry
- */
- public String getName() {
- return zipEntry.getName();
- }
-
- /**
- * Get the modification time for this BundleEntry.
- * <p>If the modification time has not been set,
- * this method will return <tt>-1</tt>.
- *
- * @return last modification time.
- */
- public long getTime() {
- return zipEntry.getTime();
- }
-
- public URL getLocalURL() {
- try {
- return new URL("jar:file:" + bundleFile.basefile.getAbsolutePath() + "!/" + zipEntry.getName()); //$NON-NLS-1$//$NON-NLS-2$
- } catch (MalformedURLException e) {
- //This can not happen.
- return null;
- }
- }
-
- public URL getFileURL() {
- try {
- File file = bundleFile.getFile(zipEntry.getName());
- if (file != null)
- return file.toURL();
- } catch (MalformedURLException e) {
- //This can not happen.
- }
- return null;
- }
- }
-
- /**
- * A BundleEntry represented by a File object. The FileBundleEntry class is
- * used for bundles that are installed as extracted zips on a file system.
- */
- public static class FileBundleEntry extends BundleEntry {
- /**
- * File for this entry.
- */
- private File file;
- /**
- * The name for this entry
- */
- private String name;
-
- /**
- * Constructs the BundleEntry using a File.
- * @param file BundleFile object this entry is a member of
- * @param name the name of this BundleEntry
- */
- FileBundleEntry(File file, String name) {
- this.file = file;
- this.name = name;
- }
-
- /**
- * Return an InputStream for the entry.
- *
- * @return InputStream for the entry
- * @exception java.io.IOException
- */
- public InputStream getInputStream() throws IOException {
- return BundleFile.secureAction.getFileInputStream(file);
- }
-
- /**
- * Return size of the uncompressed entry.
- *
- * @return size of entry
- */
- public long getSize() {
- return BundleFile.secureAction.length(file);
- }
-
- /**
- * Return name of the entry.
- *
- * @return name of entry
- */
- public String getName() {
- return (name);
- }
-
- /**
- * Get the modification time for this BundleEntry.
- * <p>If the modification time has not been set,
- * this method will return <tt>-1</tt>.
- *
- * @return last modification time.
- */
- public long getTime() {
- return BundleFile.secureAction.lastModified(file);
- }
-
- public URL getLocalURL() {
- return getFileURL();
- }
-
- public URL getFileURL() {
- try {
- return file.toURL();
- } catch (MalformedURLException e) {
- return null;
- }
- }
- }
-
- /**
- * Represents a directory entry in a ZipBundleFile. This object is used to
- * reference a directory entry in a ZipBundleFile when the directory entries are
- * not included in the zip file.
- */
- public static class DirZipBundleEntry extends BundleEntry {
-
- /**
- * ZipBundleFile for this entry.
- */
- private BundleFile.ZipBundleFile bundleFile;
- /**
- * The name for this entry
- */
- private String name;
-
- public DirZipBundleEntry(BundleFile.ZipBundleFile bundleFile, String name) {
- this.name = (name.length() > 0 && name.charAt(0) == '/') ? name.substring(1) : name;
- this.bundleFile = bundleFile;
- }
-
- public InputStream getInputStream() throws IOException {
- return null;
- }
-
- public long getSize() {
- return 0;
- }
-
- public String getName() {
- return name;
- }
-
- public long getTime() {
- return 0;
- }
-
- public URL getLocalURL() {
- try {
- return new URL("jar:file:" + bundleFile.basefile.getAbsolutePath() + "!/" + name); //$NON-NLS-1$ //$NON-NLS-2$
- } catch (MalformedURLException e) {
- //This can not happen, unless the jar protocol is not supported.
- return null;
- }
- }
-
- public URL getFileURL() {
- try {
- return bundleFile.extractDirectory(name).toURL();
- } catch (MalformedURLException e) {
- // this cannot happen.
- return null;
- }
- }
- }
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleFile.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleFile.java
deleted file mode 100644
index 1365523a4..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleFile.java
+++ /dev/null
@@ -1,597 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.adaptor.core;
-
-import java.io.*;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.*;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import org.eclipse.osgi.framework.adaptor.BundleData;
-import org.eclipse.osgi.framework.debug.Debug;
-import org.eclipse.osgi.framework.internal.core.Constants;
-import org.eclipse.osgi.framework.internal.protocol.bundleresource.Handler;
-import org.eclipse.osgi.framework.util.SecureAction;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.FrameworkEvent;
-
-/**
- * The BundleFile API is used by Adaptors to read resources out of an
- * installed Bundle in the Framework.
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.1
- */
-abstract public class BundleFile {
- static final SecureAction secureAction = new SecureAction();
- /**
- * The File object for this BundleFile.
- */
- protected File basefile;
-
- /**
- * Default constructor
- *
- */
- public BundleFile() {
- // do nothing
- }
-
- /**
- * BundleFile constructor
- * @param basefile The File object where this BundleFile is
- * persistently stored.
- */
- public BundleFile(File basefile) {
- this.basefile = basefile;
- }
-
- /**
- * Returns a File for the bundle entry specified by the path.
- * If required the content of the bundle entry is extracted into a file
- * on the file system.
- * @param path The path to the entry to locate a File for.
- * @return A File object to access the contents of the bundle entry.
- */
- abstract public File getFile(String path);
-
- /**
- * Locates a file name in this bundle and returns a BundleEntry object
- *
- * @param path path of the entry to locate in the bundle
- * @return BundleEntry object or null if the file name
- * does not exist in the bundle
- */
- abstract public BundleEntry getEntry(String path);
-
- /**
- * Allows to access the entries of the bundle.
- * Since the bundle content is usually a jar, this
- * allows to access the jar contents.
- *
- * GetEntryPaths allows to enumerate the content of "path".
- * If path is a directory, it is equivalent to listing the directory
- * contents. The returned names are either files or directories
- * themselves. If a returned name is a directory, it finishes with a
- * slash. If a returned name is a file, it does not finish with a slash.
- * @param path path of the entry to locate in the bundle
- * @return an Enumeration of Strings that indicate the paths found or
- * null if the path does not exist.
- */
- abstract public Enumeration getEntryPaths(String path);
-
- /**
- * Closes the BundleFile.
- * @throws IOException if any error occurs.
- */
- abstract public void close() throws IOException;
-
- /**
- * Opens the BundleFiles.
- * @throws IOException if any error occurs.
- */
- abstract public void open() throws IOException;
-
- /**
- * Determines if any BundleEntries exist in the given directory path.
- * @param dir The directory path to check existence of.
- * @return true if the BundleFile contains entries under the given directory path;
- * false otherwise.
- */
- abstract public boolean containsDir(String dir);
-
- /**
- * Returns a URL to access the contents of the entry specified by the path
- * @param path the path to the resource
- * @param hostBundleID the host bundle ID
- */
- public URL getResourceURL(String path, long hostBundleID) {
- return getResourceURL(path, hostBundleID, 0);
- }
-
- /**
- * Returns a URL to access the contents of the entry specified by the path
- * @param path the path to the resource
- * @param hostBundleID the host bundle ID
- * @param index the resource index
- */
- public URL getResourceURL(String path, long hostBundleID, int index) {
- BundleEntry bundleEntry = getEntry(path);
- if (bundleEntry == null)
- return null;
- if (path.length() == 0 || path.charAt(0) != '/')
- path = '/' + path;
- try {
- //use the constant string for the protocol to prevent duplication
- return secureAction.getURL(Constants.OSGI_RESOURCE_URL_PROTOCOL, Long.toString(hostBundleID), index, path, new Handler(bundleEntry));
- } catch (MalformedURLException e) {
- return null;
- }
- }
-
- /**
- * A BundleFile that uses a ZipFile as it base file.
- */
- public static class ZipBundleFile extends BundleFile {
- /**
- * The bundle data
- */
- protected BundleData bundledata;
- /**
- * The zip file
- */
- protected ZipFile zipFile;
- /**
- * The closed flag
- */
- protected boolean closed = true;
-
- /**
- * Constructs a ZipBundle File
- * @param basefile the base file
- * @param bundledata the bundle data
- * @throws IOException
- */
- public ZipBundleFile(File basefile, BundleData bundledata) throws IOException {
- super(basefile);
- if (!secureAction.exists(basefile))
- throw new IOException(NLS.bind(AdaptorMsg.ADAPTER_FILEEXIST_EXCEPTION, basefile));
- this.bundledata = bundledata;
- this.closed = true;
- }
-
- /**
- * Checks if the zip file is open
- * @return true if the zip file is open
- */
- protected boolean checkedOpen() {
- try {
- return getZipFile() != null;
- } catch (IOException e) {
- AbstractBundleData abstractData = (AbstractBundleData) bundledata;
- abstractData.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, abstractData.getBundle(), e);
- return false;
- }
- }
-
- /**
- * Opens the ZipFile for this bundle file
- * @return an open ZipFile for this bundle file
- * @throws IOException
- */
- protected ZipFile basicOpen() throws IOException {
- return secureAction.getZipFile(this.basefile);
- }
-
- /**
- * Returns an open ZipFile for this bundle file. If an open
- * ZipFile does not exist then a new one is created and
- * returned.
- * @return an open ZipFile for this bundle
- * @throws IOException
- */
- protected ZipFile getZipFile() throws IOException {
- if (closed) {
- zipFile = basicOpen();
- closed = false;
- }
- return zipFile;
- }
-
- private ZipEntry getZipEntry(String path) {
- if (path.length() > 0 && path.charAt(0) == '/')
- path = path.substring(1);
- ZipEntry entry = zipFile.getEntry(path);
- if (entry != null && entry.getSize() == 0 && !entry.isDirectory()) {
- // work around the directory bug see bug 83542
- ZipEntry dirEntry = zipFile.getEntry(path + '/');
- if (dirEntry != null)
- entry = dirEntry;
- }
- return entry;
- }
-
- /**
- * Extracts a directory and all sub content to disk
- * @param dirName the directory name to extract
- * @return the File used to extract the content to. A value
- * of <code>null</code> is returned if the directory to extract does
- * not exist or if content extraction is not supported.
- */
- protected File extractDirectory(String dirName) {
- if (!checkedOpen())
- return null;
- Enumeration entries = zipFile.entries();
- while (entries.hasMoreElements()) {
- String entryPath = ((ZipEntry) entries.nextElement()).getName();
- if (entryPath.startsWith(dirName) && !entryPath.endsWith("/")) //$NON-NLS-1$
- getFile(entryPath);
- }
- return getExtractFile(dirName);
- }
-
- private File getExtractFile(String entryName) {
- if (!(bundledata instanceof AbstractBundleData))
- return null;
- String path = ".cp"; /* put all these entries in this subdir *///$NON-NLS-1$
- String name = entryName.replace('/', File.separatorChar);
- if ((name.length() > 1) && (name.charAt(0) == File.separatorChar)) /* if name has a leading slash */
- path = path.concat(name);
- else
- path = path + File.separator + name;
- // first check the child generation dir
- File childGenDir = ((AbstractBundleData) bundledata).getGenerationDir();
- if (childGenDir != null) {
- File childPath = new File(childGenDir, path);
- if (childPath.exists())
- return childPath;
- }
- // now check the parent
- File parentGenDir = ((AbstractBundleData) bundledata).getParentGenerationDir();
- if (parentGenDir != null) {
- // there is a parent generation check if the file exists
- File parentPath = new File(parentGenDir, path);
- if (parentPath.exists())
- // only use the parent generation file if it exists; do not extract there
- return parentPath;
- }
- // did not exist in both locations; create a file for extraction.
- File bundleGenerationDir = ((AbstractBundleData) bundledata).createGenerationDir();
- /* if the generation dir exists, then we have place to cache */
- if (bundleGenerationDir != null && bundleGenerationDir.exists())
- return new File(bundleGenerationDir, path);
- return null;
- }
-
- public File getFile(String entry) {
- if (!checkedOpen())
- return null;
- ZipEntry zipEntry = getZipEntry(entry);
- if (zipEntry == null) {
- return null;
- }
-
- try {
- File nested = getExtractFile(zipEntry.getName());
- if (nested != null) {
- if (nested.exists()) {
- /* the entry is already cached */
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("File already present: " + nested.getPath()); //$NON-NLS-1$
- }
- } else {
- if (zipEntry.getName().endsWith("/")) { //$NON-NLS-1$
- if (!nested.mkdirs()) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to create directory: " + nested.getPath()); //$NON-NLS-1$
- }
- throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, nested.getAbsolutePath()));
- }
- extractDirectory(zipEntry.getName());
- } else {
- InputStream in = zipFile.getInputStream(zipEntry);
- if (in == null)
- return null;
- /* the entry has not been cached */
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Creating file: " + nested.getPath()); //$NON-NLS-1$
- }
- /* create the necessary directories */
- File dir = new File(nested.getParent());
- if (!dir.exists() && !dir.mkdirs()) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to create directory: " + dir.getPath()); //$NON-NLS-1$
- }
- throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, dir.getAbsolutePath()));
- }
- /* copy the entry to the cache */
- AbstractFrameworkAdaptor.readFile(in, nested);
- }
- }
-
- return nested;
- }
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.printStackTrace(e);
- }
- }
- return null;
- }
-
- public boolean containsDir(String dir) {
- if (!checkedOpen())
- return false;
- if (dir == null)
- return false;
-
- if (dir.length() == 0)
- return true;
-
- if (dir.charAt(0) == '/') {
- if (dir.length() == 1)
- return true;
- dir = dir.substring(1);
- }
-
- if (dir.length() > 0 && dir.charAt(dir.length() - 1) != '/')
- dir = dir + '/';
-
- Enumeration entries = zipFile.entries();
- ZipEntry zipEntry;
- String entryPath;
- while (entries.hasMoreElements()) {
- zipEntry = (ZipEntry) entries.nextElement();
- entryPath = zipEntry.getName();
- if (entryPath.startsWith(dir)) {
- return true;
- }
- }
- return false;
- }
-
- public BundleEntry getEntry(String path) {
- if (!checkedOpen())
- return null;
- ZipEntry zipEntry = getZipEntry(path);
- if (zipEntry == null) {
- if (path.length() == 0 || path.charAt(path.length() - 1) == '/') {
- // this is a directory request lets see if any entries exist in this directory
- if (containsDir(path))
- return new BundleEntry.DirZipBundleEntry(this, path);
- }
- return null;
- }
-
- return new BundleEntry.ZipBundleEntry(zipEntry, this);
-
- }
-
- public Enumeration getEntryPaths(String path) {
- if (!checkedOpen())
- return null;
- if (path == null) {
- throw new NullPointerException();
- }
-
- if (path.length() > 0 && path.charAt(0) == '/') {
- path = path.substring(1);
- }
- if (path.length() > 0 && path.charAt(path.length() - 1) != '/') {
- path = new StringBuffer(path).append("/").toString(); //$NON-NLS-1$
- }
-
- Vector vEntries = new Vector();
- Enumeration entries = zipFile.entries();
- while (entries.hasMoreElements()) {
- ZipEntry zipEntry = (ZipEntry) entries.nextElement();
- String entryPath = zipEntry.getName();
- if (entryPath.startsWith(path)) {
- if (path.length() < entryPath.length()) {
- if (entryPath.lastIndexOf('/') < path.length()) {
- vEntries.add(entryPath);
- } else {
- entryPath = entryPath.substring(path.length());
- int slash = entryPath.indexOf('/');
- entryPath = path + entryPath.substring(0, slash + 1);
- if (!vEntries.contains(entryPath)) {
- vEntries.add(entryPath);
- }
- }
- }
- }
- }
- return vEntries.size() == 0 ? null : vEntries.elements();
- }
-
- public void close() throws IOException {
- if (!closed) {
- closed = true;
- zipFile.close();
- }
- }
-
- public void open() {
- //do nothing
- }
-
- }
-
- /**
- * A BundleFile that uses a directory as its base file.
- */
- public static class DirBundleFile extends BundleFile {
-
- /**
- * Constructs a DirBundleFile
- * @param basefile the base file
- * @throws IOException
- */
- public DirBundleFile(File basefile) throws IOException {
- super(basefile);
- if (!secureAction.exists(basefile) || !secureAction.isDirectory(basefile)) {
- throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_EXCEPTION, basefile));
- }
- }
-
- public File getFile(String path) {
- File filePath = new File(this.basefile, path);
- if (secureAction.exists(filePath)) {
- return filePath;
- }
- return null;
- }
-
- public BundleEntry getEntry(String path) {
- File filePath = new File(this.basefile, path);
- if (!secureAction.exists(filePath)) {
- return null;
- }
- return new BundleEntry.FileBundleEntry(filePath, path);
- }
-
- public boolean containsDir(String dir) {
- File dirPath = new File(this.basefile, dir);
- return secureAction.exists(dirPath) && secureAction.isDirectory(dirPath);
- }
-
- public Enumeration getEntryPaths(final String path) {
- final java.io.File pathFile = new java.io.File(basefile, path);
- if (!secureAction.exists(pathFile))
- return null;
- if (secureAction.isDirectory(pathFile)) {
- final String[] fileList = secureAction.list(pathFile);
- if (fileList == null || fileList.length == 0)
- return null;
- final String dirPath = path.length() == 0 || path.charAt(path.length() - 1) == '/' ? path : path + '/';
- return new Enumeration() {
- int cur = 0;
-
- public boolean hasMoreElements() {
- return fileList != null && cur < fileList.length;
- }
-
- public Object nextElement() {
- if (!hasMoreElements()) {
- throw new NoSuchElementException();
- }
- java.io.File childFile = new java.io.File(pathFile, fileList[cur]);
- StringBuffer sb = new StringBuffer(dirPath).append(fileList[cur++]);
- if (secureAction.isDirectory(childFile)) {
- sb.append("/"); //$NON-NLS-1$
- }
- return sb.toString();
- }
-
- };
- }
- return new Enumeration() {
- int cur = 0;
-
- public boolean hasMoreElements() {
- return cur < 1;
- }
-
- public Object nextElement() {
- if (cur == 0) {
- cur = 1;
- return path;
- }
- throw new NoSuchElementException();
- }
- };
- }
-
- public void close() {
- // nothing to do.
- }
-
- public void open() {
- // nothing to do.
- }
- }
-
- /**
- * A NestedDirBundleFile uses another BundleFile as its source but
- * accesses all of its resources relative to a nested directory within
- * the other BundleFile object. This is used to support zipped bundles
- * that use a Bundle-ClassPath with an nested directory specified.
- * <p>
- * For Example:
- * <pre>
- * Bundle-ClassPath: nested.jar,nesteddir/
- * </pre>
- */
- public static class NestedDirBundleFile extends BundleFile {
- BundleFile baseBundleFile;
- String cp;
-
- /**
- * Constructs a NestedDirBundleFile
- * @param baseBundlefile the base bundle file
- * @param cp
- */
- public NestedDirBundleFile(BundleFile baseBundlefile, String cp) {
- super(baseBundlefile.basefile);
- this.baseBundleFile = baseBundlefile;
- this.cp = cp;
- if (cp.charAt(cp.length() - 1) != '/') {
- this.cp = this.cp + '/';
- }
- }
-
- public void close() {
- // do nothing.
- }
-
- public BundleEntry getEntry(String path) {
- if (path.length() > 0 && path.charAt(0) == '/')
- path = path.substring(1);
- String newpath = new StringBuffer(cp).append(path).toString();
- return baseBundleFile.getEntry(newpath);
- }
-
- public boolean containsDir(String dir) {
- if (dir == null)
- return false;
-
- if (dir.length() > 0 && dir.charAt(0) == '/')
- dir = dir.substring(1);
- String newdir = new StringBuffer(cp).append(dir).toString();
- return baseBundleFile.containsDir(newdir);
- }
-
- public Enumeration getEntryPaths(String path) {
- // getEntryPaths is only valid if this is a root bundle file.
- return null;
- }
-
- public File getFile(String entry) {
- // getFile is only valid if this is a root bundle file.
- return null;
- }
-
- public void open() throws IOException{
- // do nothing
- }
- }
-
- /**
- * Returns the base file for this BundleFile
- * @return the base file for this BundleFile
- */
- public File getBaseFile() {
- return basefile;
- }
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleInstaller.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleInstaller.java
deleted file mode 100644
index 66235db51..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/BundleInstaller.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.osgi.framework.adaptor.core;
-
-import org.eclipse.osgi.service.resolver.BundleDescription;
-import org.osgi.framework.BundleException;
-
-/**
- * A bundle installer allows the platform admin implementation to
- * delegate the behavior of installing/uninstalling bundles to
- * another object.
- * <p>
- * Clients may implement this interface.
- * </p>
- * @since 3.1
- * @see StateManager#commit
- */
-public interface BundleInstaller {
- /**
- * Installs a bundle associated with the specified BundleDescription
- * @param toInstall the BundleDescription associated with the bundle to install
- * @throws BundleException if an error occurs while installing the bundle
- */
- public void installBundle(BundleDescription toInstall) throws BundleException;
-
- /**
- * Uninstalls a bundle associated with the specified BundleDescription
- * @param toUninstall the BundleDescriptoin associated with the bundle to uninstall
- * @throws BundleException if an error occurs while uninstalling the bundle
- */
- public void uninstallBundle(BundleDescription toUninstall) throws BundleException;
-
- /**
- * Updates a bundle associated with the specified BundleDescription
- * @param toRefresh the BundleDescription associated with the bundle to update
- * @throws BundleException if an error occurs while updating the bundle
- */
- public void updateBundle(BundleDescription toRefresh) throws BundleException;
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/DefaultClassLoader.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/DefaultClassLoader.java
deleted file mode 100644
index fe83979a7..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/DefaultClassLoader.java
+++ /dev/null
@@ -1,722 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.adaptor.core;
-
-import java.io.*;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.security.*;
-import java.security.cert.Certificate;
-import java.util.*;
-import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
-import org.eclipse.osgi.framework.debug.Debug;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.FrameworkEvent;
-
-/**
- * A concrete implementation of BundleClassLoader. This implementation
- * consolidates all Bundle-ClassPath entries into a single ClassLoader.
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.1
- */
-public class DefaultClassLoader extends AbstractClassLoader {
- /**
- * A PermissionCollection for AllPermissions; shared across all ProtectionDomains when security is disabled
- */
- static final PermissionCollection ALLPERMISSIONS;
- static {
- AllPermission allPerm = new AllPermission();
- ALLPERMISSIONS = allPerm.newPermissionCollection();
- if (ALLPERMISSIONS != null)
- ALLPERMISSIONS.add(allPerm);
- }
- /**
- * The BundleData object for this BundleClassLoader
- */
- protected AbstractBundleData hostdata;
-
- /**
- * The ClasspathEntries for this BundleClassLoader. Each ClasspathEntry object
- * represents on Bundle-ClassPath entry.
- */
- protected ClasspathEntry[] classpathEntries;
-
- /**
- * A list of fragment classpaths for this classloader
- */
- protected Vector fragClasspaths; //TODO This should be an array or an arraylist if the synchronization is not required
-
- /**
- * The buffer size to use when loading classes. This value is used
- * only if we cannot determine the size of the class we are loading.
- */
- protected int buffersize = 8 * 1024; //TODO Could not that be a constant?
-
- /**
- * BundleClassLoader constructor.
- * @param delegate The ClassLoaderDelegate for this ClassLoader.
- * @param domain The ProtectionDomain for this ClassLoader.
- * @param classpath An array of Bundle-ClassPath entries to
- * use for loading classes and resources. This is specified by the
- * Bundle-ClassPath manifest entry.
- * @param parent The parent ClassLoader.
- * @param bundledata The BundleData for this ClassLoader
- */
- public DefaultClassLoader(ClassLoaderDelegate delegate, ProtectionDomain domain, String[] classpath, ClassLoader parent, AbstractBundleData bundledata) {
- super(delegate, domain, classpath, parent);
- this.hostdata = bundledata;
-
- try {
- hostdata.open(); /* make sure the BundleData is open */
- } catch (IOException e) {
- hostdata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, hostdata.getBundle(), e);
- }
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.BundleClassLoader#initialize()
- */
- public void initialize() {
- classpathEntries = buildClasspath(hostclasspath, hostdata, hostdomain);
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.BundleClassLoader#attachFragment(BundleData, ProtectionDomain, String[])
- */
- public void attachFragment(org.eclipse.osgi.framework.adaptor.BundleData bundledata, ProtectionDomain domain, String[] classpath) {
- AbstractBundleData abstractbundledata = (AbstractBundleData) bundledata;
- try {
- bundledata.open(); /* make sure the BundleData is open */
- } catch (IOException e) {
-
- abstractbundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, abstractbundledata.getBundle(), e);
- }
- ClasspathEntry[] fragEntries = buildClasspath(classpath, abstractbundledata, domain);
- FragmentClasspath fragClasspath = new FragmentClasspath(fragEntries, abstractbundledata, domain);
- insertFragment(fragClasspath);
- }
-
- /**
- * Inserts a fragment classpath to into the list of fragments for this host.
- * Fragments are inserted into the list according to the fragment's
- * Bundle ID.
- * @param fragClasspath The FragmentClasspath to insert.
- */
- protected synchronized void insertFragment(FragmentClasspath fragClasspath) {
- if (fragClasspaths == null) {
- // First fragment to attach. Simply create the list and add the fragment.
- fragClasspaths = new Vector(10);
- fragClasspaths.addElement(fragClasspath);
- return;
- }
-
- // Find a place in the fragment list to insert this fragment.
- int size = fragClasspaths.size();
- long fragID = fragClasspath.bundledata.getBundleID();
- for (int i = 0; i < size; i++) {
- long otherID = ((FragmentClasspath) fragClasspaths.elementAt(i)).bundledata.getBundleID();
- if (fragID < otherID) {
- fragClasspaths.insertElementAt(fragClasspath, i);
- return;
- }
- }
- // This fragment has the highest ID; put it at the end of the list.
- fragClasspaths.addElement(fragClasspath);
- }
-
- /**
- * Returns a string of the symbolic name and version
- * @return a string of the symbolic name and version
- */
- protected String getBundleSymbolicName() {
- return hostdata.getSymbolicName() + "_" + hostdata.getVersion(); //$NON-NLS-1$
- }
-
- /**
- * Returns the host BundleData for this classloader
- * @return the host BundleData for this classloader
- */
- public AbstractBundleData getHostData() {
- return hostdata;
- }
-
- /**
- * Returns a list of FragmentClasspath objects for the currently attached fragments
- * @return a list of FragmentClasspath objects for the currently attached fragments
- */
- public FragmentClasspath[] getFragClasspaths() {
- if (fragClasspaths == null)
- return null;
- return (FragmentClasspath[]) fragClasspaths.toArray(new FragmentClasspath[fragClasspaths.size()]);
- }
-
- /**
- * Gets a ClasspathEntry object for the specified ClassPath entry.
- * @param cp The ClassPath entry to get the ClasspathEntry for.
- * @param bundledata The BundleData that the ClassPath entry is for.
- * @param domain The ProtectionDomain for the ClassPath entry.
- * @return The ClasspathEntry object for the ClassPath entry.
- */
- protected ClasspathEntry getClasspath(String cp, AbstractBundleData bundledata, ProtectionDomain domain) {
- BundleFile bundlefile = null;
- File file;
- // check for internal library jars
- if ((file = bundledata.getBaseBundleFile().getFile(cp)) != null)
- bundlefile = createBundleFile(file, bundledata);
- // check for intenral library directories in a bundle jar file
- if (bundlefile == null && bundledata.getBaseBundleFile().containsDir(cp))
- bundlefile = new BundleFile.NestedDirBundleFile(bundledata.getBaseBundleFile(), cp);
- // if in dev mode, try using the cp as an absolute path
- if (bundlefile == null && DevClassPathHelper.inDevelopmentMode())
- return getExternalClassPath(cp, bundledata, domain);
- if (bundlefile != null)
- return createClassPathEntry(bundlefile, domain);
- return null;
- }
-
- /**
- * Gets a ClasspathEntry object for the specified classpath entry which is external to the
- * bundledata.
- * @param cp The ClassPath entry to get the ClasspathEntry for.
- * @param bundledata The BundleData that the ClassPath entry is for.
- * @param domain The ProtectionDomain for the ClassPath entry.
- * @return The ClasspathEntry object for the ClassPath entry.
- */
- protected ClasspathEntry getExternalClassPath(String cp, AbstractBundleData bundledata, ProtectionDomain domain) {
- File file = new File(cp);
- if (!file.isAbsolute())
- return null;
- BundleFile bundlefile = createBundleFile(file, bundledata);
- if (bundlefile != null)
- return createClassPathEntry(bundlefile, domain);
- return null;
- }
-
- /**
- * Creates a BundleFile object for a classpath entry
- * @param file the file object used to create a BundleFile
- * @param bundledata the bundle data
- * @return a BundleFile object for a classpath entry
- */
- protected BundleFile createBundleFile(File file, AbstractBundleData bundledata) {
- if (file == null || !file.exists())
- return null;
- try {
- return hostdata.getAdaptor().createBundleFile(file, bundledata);
- } catch (IOException e) {
- bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e);
- }
- return null;
- }
-
- /**
- * @see ClassLoader#findClass(java.lang.String)
- */
- protected synchronized Class findClass(String name) throws ClassNotFoundException {
- // must call findLoadedClass here even if it was called earlier,
- // the findLoadedClass and defineClass calls must be atomic
- Class result = findLoadedClass(name);
- if (result != null)
- return result;
- for (int i = 0; i < classpathEntries.length; i++) {
- if (classpathEntries[i] != null) {
- result = findClassImpl(name, classpathEntries[i]);
- if (result != null)
- return result;
- }
- }
- // look in fragments.
- if (fragClasspaths != null) {
- int size = fragClasspaths.size();
- for (int i = 0; i < size; i++) {
- FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
- for (int j = 0; j < fragCP.classpathEntries.length; j++) {
- result = findClassImpl(name, fragCP.classpathEntries[j]);
- if (result != null)
- return result;
- }
- }
- }
- throw new ClassNotFoundException(name);
- }
-
- /**
- * Finds a class in the BundleFile. If a class is found then the class
- * is defined using the ProtectionDomain bundledomain.
- * @param name The name of the class to find.
- * @param classpathEntry The ClasspathEntry to find the class in.
- * @return The loaded class object or null if the class is not found.
- */
- protected Class findClassImpl(String name, ClasspathEntry classpathEntry) {
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println("BundleClassLoader[" + hostdata + "].findClass(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
- }
-
- String filename = name.replace('.', '/').concat(".class"); //$NON-NLS-1$
-
- BundleEntry entry = classpathEntry.getBundleFile().getEntry(filename);
-
- if (entry == null) {
- return null;
- }
-
- InputStream in;
- try {
- in = entry.getInputStream();
- } catch (IOException e) {
- return null;
- }
-
- int length = (int) entry.getSize();
- byte[] classbytes;
- int bytesread = 0;
- int readcount;
-
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println(" about to read " + length + " bytes from " + filename); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- try {
- try {
- if (length > 0) {
- classbytes = new byte[length];
-
- readloop: for (; bytesread < length; bytesread += readcount) {
- readcount = in.read(classbytes, bytesread, length - bytesread);
-
- if (readcount <= 0) /* if we didn't read anything */{
- break readloop; /* leave the loop */
- }
- }
- } else /* BundleEntry does not know its own length! */{
- length = buffersize;
- classbytes = new byte[length];
-
- readloop: while (true) {
- for (; bytesread < length; bytesread += readcount) {
- readcount = in.read(classbytes, bytesread, length - bytesread);
-
- if (readcount <= 0) /* if we didn't read anything */{
- break readloop; /* leave the loop */
- }
- }
-
- byte[] oldbytes = classbytes;
- length += buffersize;
- classbytes = new byte[length];
- System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
- }
- }
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println(" IOException reading " + filename + " from " + hostdata); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- return null;
- }
- } finally {
- try {
- in.close();
- } catch (IOException ee) {
- // nothing to do here
- }
- }
-
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println(" read " + bytesread + " bytes from " + filename); //$NON-NLS-1$ //$NON-NLS-2$
- Debug.println(" defining class " + name); //$NON-NLS-1$
- }
-
- try {
- return (defineClass(name, classbytes, 0, bytesread, classpathEntry));
- } catch (Error e) {
- if (Debug.DEBUG && Debug.DEBUG_LOADER) {
- Debug.println(" error defining class " + name); //$NON-NLS-1$
- }
-
- throw e;
- }
- }
-
- /**
- * Defines a class for this classloader
- * @param name the name of the class
- * @param classbytes the class bytes
- * @param off the offset in the class bytes array
- * @param len the legth of the class bytes
- * @param classpathEntry the classpath entry used for the class
- * @return a loaded Class object
- * @throws ClassFormatError if the class has a format error
- */
- protected Class defineClass(String name, byte[] classbytes, int off, int len, ClasspathEntry classpathEntry) throws ClassFormatError {
- if (name != null && name.startsWith("java.")) { //$NON-NLS-1$
- // To work around the security issue that prevents any
- // other classloader except for the bootstrap classloader
- // from loading packages that start with java.
- name = null;
- }
- return defineClass(name, classbytes, off, len, classpathEntry.getProtectionDomain());
- }
-
- /**
- * @see ClassLoader#findResource(java.lang.String)
- */
- protected URL findResource(String name) {
- URL result = null;
- for (int i = 0; i < classpathEntries.length; i++) {
- if (classpathEntries[i] != null) {
- result = findResourceImpl(name, classpathEntries[i].getBundleFile());
- if (result != null)
- return result;
- }
- }
- // look in fragments
- if (fragClasspaths != null) {
- int size = fragClasspaths.size();
- for (int i = 0; i < size; i++) {
- FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
- for (int j = 0; j < fragCP.classpathEntries.length; j++) {
- result = findResourceImpl(name, fragCP.classpathEntries[j].getBundleFile());
- if (result != null)
- return result;
- }
- }
- }
- return null;
- }
-
- /**
- * Looks in the specified BundleFile for the resource.
- * @param name The name of the resource to find.
- * @param bundlefile The BundleFile to look in.
- * @return A URL to the resource or null if the resource does not exist.
- */
- protected URL findResourceImpl(String name, BundleFile bundlefile) {
- return findResourceImpl(name, bundlefile, 0);
- }
-
- /**
- * Looks in the specified BundleFile for the resource.
- * @param name The name of the resource to find.
- * @param bundlefile The BundleFile to look in.
- * @param index the index of the resource.
- * @return A URL to the resource or null if the resource does not exist.
- */
- protected URL findResourceImpl(String name, BundleFile bundlefile, int index) {
- return bundlefile.getResourceURL(name, hostdata.getBundleID(), index);
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.BundleClassLoader#findLocalResources(String)
- */
- public Enumeration findLocalResources(String resource) {
- Vector resources = new Vector(6); // use a Vector instead of ArrayList because we need an enumeration
- for (int i = 0; i < classpathEntries.length; i++) {
- if (classpathEntries[i] != null) {
- URL url = findResourceImpl(resource, classpathEntries[i].getBundleFile(), resources.size());
- if (url != null)
- resources.addElement(url);
- }
- }
- // look in fragments
- if (fragClasspaths != null) {
- int size = fragClasspaths.size();
- for (int i = 0; i < size; i++) {
- FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
- for (int j = 0; j < fragCP.classpathEntries.length; j++) {
- URL url = findResourceImpl(resource, fragCP.classpathEntries[j].getBundleFile(), resources.size());
- if (url != null)
- resources.addElement(url);
- }
- }
- }
- if (resources.size() > 0)
- return resources.elements();
- return null;
- }
-
- /**
- * @see AbstractClassLoader#findLocalObject(String)
- */
- public Object findLocalObject(String object) {
- BundleEntry result = null;
- for (int i = 0; i < classpathEntries.length; i++) {
- if (classpathEntries[i] != null) {
- result = findObjectImpl(object, classpathEntries[i].getBundleFile());
- if (result != null) {
- return result;
- }
- }
- }
- // look in fragments
- if (fragClasspaths != null) {
- int size = fragClasspaths.size();
- for (int i = 0; i < size; i++) {
- FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
- for (int j = 0; j < fragCP.classpathEntries.length; j++) {
- result = findObjectImpl(object, fragCP.classpathEntries[j].getBundleFile());
- if (result != null) {
- return result;
- }
- }
- }
- }
- return null;
- }
-
- /**
- * @see AbstractClassLoader#findLocalObjects(String)
- */
- public Enumeration findLocalObjects(String object) {
- Vector objects = new Vector(6); // use a Vector instead of ArrayList because we need an enumeration
- for (int i = 0; i < classpathEntries.length; i++) {
- if (classpathEntries[i] != null) {
- Object result = findObjectImpl(object, classpathEntries[i].getBundleFile());
- if (result != null)
- objects.addElement(result);
- }
- }
- // look in fragments
- if (fragClasspaths != null) {
- int size = fragClasspaths.size();
- for (int i = 0; i < size; i++) {
- FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
- for (int j = 0; j < fragCP.classpathEntries.length; j++) {
- Object result = findObjectImpl(object, fragCP.classpathEntries[j].getBundleFile());
- if (result != null)
- objects.addElement(result);
- }
- }
- }
- if (objects.size() > 0)
- return objects.elements();
- return null;
- }
-
- /**
- * Looks in the specified BundleFile for the entry.
- * @param object The name of the entry to find.
- * @param bundleFile The BundleFile to look in.
- * @return a bundle entry for the specified entry or <code>null</code> if the
- * entry does not exist
- */
- protected BundleEntry findObjectImpl(String object, BundleFile bundleFile) {
- return bundleFile.getEntry(object);
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.BundleClassLoader#close()
- */
- public void close() {
- super.close();
- if (classpathEntries != null) {
- for (int i = 0; i < classpathEntries.length; i++) {
- if (classpathEntries[i] != null) {
- try {
- classpathEntries[i].getBundleFile().close();
- } catch (IOException e) {
- hostdata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, hostdata.getBundle(), e);
- }
- }
- }
- }
- if (fragClasspaths != null) {
- int size = fragClasspaths.size();
- for (int i = 0; i < size; i++) {
- FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
- fragCP.close();
- }
- }
- }
-
- /**
- * Builds the classpath entry objects for this classloader
- * @param classpath a list of classpath entries to build
- * @param bundledata the bundle data
- * @param domain the ProtectionDomain for the classpath entry objects
- * @return
- */
- protected ClasspathEntry[] buildClasspath(String[] classpath, AbstractBundleData bundledata, ProtectionDomain domain) {
- ArrayList result = new ArrayList(classpath.length);
- // if in dev mode add the dev entries
- addDefaultDevEntries(result, bundledata, domain);
- // add the regular classpath entries.
- for (int i = 0; i < classpath.length; i++)
- findClassPathEntry(result, classpath[i], bundledata, domain);
- return (ClasspathEntry[]) result.toArray(new ClasspathEntry[result.size()]);
- }
-
- /**
- * Adds the default development classpath entries
- * @param result a list of current classpath entries. This list is modified by this method to add
- * a new classpath entry.
- * @param bundledata the bundle data
- * @param domain the ProtectionDomain for the classpath entry
- */
- protected void addDefaultDevEntries(ArrayList result, AbstractBundleData bundledata, ProtectionDomain domain) {
- String[] devClassPath = !DevClassPathHelper.inDevelopmentMode() ? null : DevClassPathHelper.getDevClassPath(bundledata.getSymbolicName());
- if (devClassPath == null)
- return; // not in dev mode return
- for (int i = 0; i < devClassPath.length; i++)
- findClassPathEntry(result, devClassPath[i], bundledata, domain);
- }
-
- /**
- * Finds a classpath entry for this classloader
- * @param result a list of current classpath entries. This list is modified by this method to add
- * a new classpath entry.
- * @param entry the path to the entry to find
- * @param bundledata the bundle data
- * @param domain the ProtectionDomain for the classpath entry
- */
- protected void findClassPathEntry(ArrayList result, String entry, AbstractBundleData bundledata, ProtectionDomain domain) {
- if (!addClassPathEntry(result, entry, bundledata, domain)) {
- String[] devCP = !DevClassPathHelper.inDevelopmentMode() ? null : DevClassPathHelper.getDevClassPath(bundledata.getSymbolicName());
- if (devCP == null || devCP.length == 0) {
- BundleException be = new BundleException(NLS.bind(AdaptorMsg.BUNDLE_CLASSPATH_ENTRY_NOT_FOUND_EXCEPTION, entry, bundledata.getLocation()));
- bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.INFO, bundledata.getBundle(), be);
- }
- }
- }
-
- /**
- * Adds a classpath entry to this classloader
- * @param result a list of current classpath entries. This list is modified by this method to add
- * a new classpath entry.
- * @param entry the path to the entry to add
- * @param bundledata the bundle data
- * @param domain the ProtectionDomain for the classpath entry
- * @return true if a classpath entry was added to the result; false if the classpath entry could
- * not be found
- */
- protected boolean addClassPathEntry(ArrayList result, String entry, AbstractBundleData bundledata, ProtectionDomain domain) {
- if (entry.equals(".")) { //$NON-NLS-1$
- result.add(createClassPathEntry(bundledata.getBaseBundleFile(), domain));
- return true;
- }
- Object element = getClasspath(entry, bundledata, domain);
- if (element != null) {
- result.add(element);
- return true;
- }
- // need to check in fragments for the classpath entry.
- // only check for fragments if the bundledata is the hostdata.
- if (fragClasspaths != null && hostdata == bundledata) {
- int size = fragClasspaths.size();
- for (int i = 0; i < size; i++) {
- FragmentClasspath fragCP = (FragmentClasspath) fragClasspaths.elementAt(i);
- element = getClasspath(entry, fragCP.bundledata, fragCP.domain);
- if (element != null) {
- result.add(element);
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Creates a ClasspathEntry from a BundleFile and ProtectionDomain.
- * @param bundlefile the BundleFile.
- * @param domain the ProtectionDomain
- * @return the ClasspathEntry
- */
- protected ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain domain) {
- return new ClasspathEntry(bundlefile, domain);
- }
-
- /**
- * A data structure to hold information about a fragment classpath.
- */
- protected class FragmentClasspath {
- /** The ClasspathEntries of the fragments Bundle-Classpath */
- protected ClasspathEntry[] classpathEntries;
- /** The BundleData of the fragment */
- protected AbstractBundleData bundledata;
- /** The ProtectionDomain of the fragment */
- protected ProtectionDomain domain;
-
- protected FragmentClasspath(ClasspathEntry[] classpathEntries, AbstractBundleData bundledata, ProtectionDomain domain) {
- this.classpathEntries = classpathEntries;
- this.bundledata = bundledata;
- this.domain = domain;
- }
-
- protected void close() {
- for (int i = 0; i < classpathEntries.length; i++) {
- try {
- classpathEntries[i].getBundleFile().close();
- } catch (IOException e) {
- bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), e);
- }
- }
- }
-
- public AbstractBundleData getBundleData() {
- return bundledata;
- }
- }
-
- /**
- * A data structure to hold information about a classpath entry.
- */
- protected class ClasspathEntry {
- protected BundleFile bundlefile;
- protected ProtectionDomain domain;
-
- protected ClasspathEntry(BundleFile bundlefile, ProtectionDomain domain) {
- this.bundlefile = bundlefile;
- this.domain = createProtectionDomain(domain);
- }
-
- public BundleFile getBundleFile() {
- return bundlefile;
- }
-
- public ProtectionDomain getProtectionDomain() {
- return domain;
- }
-
- /*
- * Creates a ProtectionDomain using the permissions of the specified baseDomain
- */
- protected ProtectionDomain createProtectionDomain(ProtectionDomain baseDomain) {
- // create a protection domain which knows about the codesource for this classpath entry (bug 89904)
- try {
- // use the permissions supplied by the domain passed in from the framework
- PermissionCollection permissions;
- if (baseDomain != null)
- permissions = baseDomain.getPermissions();
- else
- // no domain specified. Better use a collection that has all permissions
- // this is done just incase someone sets the security manager later
- permissions = ALLPERMISSIONS;
- return new ClasspathDomain(bundlefile.getBaseFile().toURL(), permissions);
- } catch (MalformedURLException e) {
- // Failed to create our own domain; just return the baseDomain
- return baseDomain;
- }
- }
- }
-
- /*
- * Very simple protection domain that uses a URL to create a CodeSource for a ProtectionDomain
- */
- protected class ClasspathDomain extends ProtectionDomain {
- public ClasspathDomain(URL codeLocation, PermissionCollection permissions) {
- super(new CodeSource(codeLocation, (Certificate[]) null), permissions);
- }
- }
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SignedBundle.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SignedBundle.java
deleted file mode 100644
index 2459fc6a1..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SignedBundle.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.adaptor.core;
-
-import java.io.IOException;
-
-/**
- * The SignedBundle class is used to support bundle signing. Every SignedBundle wraps a
- * BundleFile object. A SignedBundle uses the wrapped BundleFile to extract signitures
- * and digents from and validates input streams for the wrapped BundleFile.
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.1
- */
-public abstract class SignedBundle extends BundleFile {
- /**
- * Sets the BundleFile for this singed bundle. It will extract
- * signatures and digests from the bundle file and validate input streams
- * before using them from the bundle file.
- *
- * @param bundleFile the BundleFile to extract elements from.
- * @throws IOException
- */
- public abstract void setBundleFile(BundleFile bundleFile) throws IOException;
-
- /**
- * Matches the distinguished name chains of a bundle's signers against a
- * pattern of a distinguished name chain.
- *
- * @param pattern the pattern of distinguished name (DN) chains to match
- * against the dnChain. Wildcards "*" can be used in three cases:
- * <ol>
- * <li>As a DN. In this case, the DN will consist of just the "*".
- * It will match zero or more DNs. For example, "cn=me,c=US;*;cn=you"
- * will match "cn=me,c=US";cn=you" and
- * "cn=me,c=US;cn=her,c=CA;cn=you".
- * <li>As a DN prefix. In this case, the DN must start with "*,".
- * The wild card will match zero or more RDNs at the start of a DN.
- * For example, "*,cn=me,c=US;cn=you" will match "cn=me,c=US";cn=you"
- * and "ou=my org unit,o=my org,cn=me,c=US;cn=you"</li>
- * <li>As a value. In this case the value of a name value pair in an
- * RDN will be a "*". The wildcard will match any value for the given
- * name. For example, "cn=*,c=US;cn=you" will match
- * "cn=me,c=US";cn=you" and "cn=her,c=US;cn=you", but it will not
- * match "ou=my org unit,c=US;cn=you". If the wildcard does not occur
- * by itself in the value, it will not be used as a wildcard. In
- * other words, "cn=m*,c=US;cn=you" represents the common name of
- * "m*" not any common name starting with "m".</li>
- * </ol>
- * @return true if a dnChain matches the pattern. A value of false is returned
- * if bundle signing is not supported.
- * @throws IllegalArgumentException
- */
- public abstract boolean matchDNChain(String pattern);
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SignedBundleSupport.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SignedBundleSupport.java
deleted file mode 100644
index 3c237a668..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/SignedBundleSupport.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.osgi.framework.adaptor.core;
-
-/**
- * Provides the implementation of signed bundle support for the framework adaptor.
- * <p>
- * Clients may implement this interface.
- * </p>
- * @since 3.1
- */
-public interface SignedBundleSupport {
- /**
- * Create a new SignedBundle object
- * @return a new SignedBundle object
- */
- public SignedBundle createSignedBundle();
-
- /**
- * Matches the distinguished name chain against a pattern of a distinguished name chain.
- *
- * @param pattern the pattern of distinguished name (DN) chains to match
- * against the dnChain.
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#matchDNChain(String, String[])
- * @return true if a dnChain matches the pattern. A value of false is returned
- * if bundle signing is not supported.
- * @throws IllegalArgumentException
- */
- public boolean matchDNChain(String pattern, String dnChain[]);
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/BundleResourceHandler.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/BundleResourceHandler.java
index d0cd3fdbd..a7d663091 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/BundleResourceHandler.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/BundleResourceHandler.java
@@ -13,8 +13,9 @@ package org.eclipse.osgi.framework.internal.core;
import java.io.IOException;
import java.net.*;
-import org.eclipse.osgi.framework.adaptor.BundleClassLoader;
-import org.eclipse.osgi.framework.adaptor.core.*;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
+import org.eclipse.osgi.internal.baseadaptor.AdaptorMsg;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
@@ -133,14 +134,14 @@ public abstract class BundleResourceHandler extends URLStreamHandler {
String bidString = url.getHost();
if (bidString == null) {
- throw new IOException(NLS.bind(AdaptorMsg.URL_NO_BUNDLE_ID, url.toExternalForm()));
+ throw new IOException(NLS.bind(AdaptorMsg.URL_NO_BUNDLE_ID, url.toExternalForm()));
}
AbstractBundle bundle = null;
long bundleID;
try {
bundleID = Long.parseLong(bidString);
} catch (NumberFormatException nfe) {
- throw new MalformedURLException(NLS.bind(AdaptorMsg.URL_INVALID_BUNDLE_ID, bidString));
+ throw new MalformedURLException(NLS.bind(AdaptorMsg.URL_INVALID_BUNDLE_ID, bidString));
}
bundle = (AbstractBundle) context.getBundle(bundleID);
// check to make sure that this URL was created using the
@@ -152,7 +153,7 @@ public abstract class BundleResourceHandler extends URLStreamHandler {
}
if (bundle == null) {
- throw new IOException(NLS.bind(AdaptorMsg.URL_NO_BUNDLE_FOUND, url.toExternalForm()));
+ throw new IOException(NLS.bind(AdaptorMsg.URL_NO_BUNDLE_FOUND, url.toExternalForm()));
}
return (new BundleURLConnection(url, findBundleEntry(url, bundle)));
}
@@ -266,10 +267,10 @@ public abstract class BundleResourceHandler extends URLStreamHandler {
}
}
- protected static BundleClassLoader getBundleClassLoader(AbstractBundle bundle) {
+ protected static BaseClassLoader getBundleClassLoader(AbstractBundle bundle) {
BundleLoader loader = bundle.getBundleLoader();
if (loader == null)
return null;
- return loader.createClassLoader();
+ return (BaseClassLoader) loader.createClassLoader();
}
}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/BundleURLConnection.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/BundleURLConnection.java
index 51dedab44..e5da6a257 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/BundleURLConnection.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/BundleURLConnection.java
@@ -1,10 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
@@ -15,8 +15,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
-import org.eclipse.osgi.framework.adaptor.core.AdaptorMsg;
-import org.eclipse.osgi.framework.adaptor.core.BundleEntry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.internal.baseadaptor.AdaptorMsg;
import org.eclipse.osgi.util.NLS;
/**
@@ -53,7 +53,7 @@ public class BundleURLConnection extends URLConnection {
in = bundleEntry.getInputStream();
connected = true;
} else {
- throw new IOException(NLS.bind(AdaptorMsg.RESOURCE_NOT_FOUND_EXCEPTION, url));
+ throw new IOException(NLS.bind(AdaptorMsg.RESOURCE_NOT_FOUND_EXCEPTION, url));
}
}
}
@@ -78,6 +78,7 @@ public class BundleURLConnection extends URLConnection {
if (in.markSupported())
contentType = guessContentTypeFromStream(in);
} catch (IOException e) {
+ // do nothing
}
}
}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/DefaultPermissionStorage.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/DefaultPermissionStorage.java
deleted file mode 100644
index d9409fd0d..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/DefaultPermissionStorage.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.internal.core;
-
-import java.io.*;
-import java.util.*;
-import org.eclipse.osgi.framework.adaptor.PermissionStorage;
-import org.eclipse.osgi.framework.adaptor.core.AbstractFrameworkAdaptor;
-import org.eclipse.osgi.framework.adaptor.core.AdaptorMsg;
-import org.eclipse.osgi.framework.debug.Debug;
-import org.eclipse.osgi.framework.internal.reliablefile.*;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * Class to model permission data storage.
- */
-
-public class DefaultPermissionStorage implements PermissionStorage {
- /** Filename used to store the ConditionalPermissions. This name
- * is relative to permissionDir.*/
- private static final String CONDPERMS = "condPerms"; //$NON-NLS-1$
- /** Directory into which permission data files are stored. */
- protected File permissionDir;
-
- /** List of permission files: String location => File permission file */
- protected Hashtable permissionFiles;
-
- /** Default permission data. */
- protected File defaultData;
-
- /** First permission data format version */
- protected static final int PERMISSIONDATA_VERSION_1 = 1;
-
- /** Current permission data format version */
- protected static final int PERMISSIONDATA_VERSION = PERMISSIONDATA_VERSION_1;
-
- /**
- * Constructor.
- *
- * @throws IOException If an error occurs initializing the object.
- */
- public DefaultPermissionStorage(AbstractFrameworkAdaptor adaptor) throws IOException {
- permissionDir = new File(adaptor.getBundleStoreRootDir(), "permdata"); //$NON-NLS-1$
- permissionFiles = new Hashtable();
-
- if (!permissionDir.exists() && !permissionDir.mkdirs()) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to create directory: " + permissionDir.getPath()); //$NON-NLS-1$
- }
-
- throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, permissionDir));
- }
-
- defaultData = new File(permissionDir, ".default"); //$NON-NLS-1$
-
- loadLocations();
- }
-
- /**
- * Returns the locations that have permission data assigned to them,
- * that is, locations for which permission data
- * exists in persistent storage.
- *
- * @return The locations that have permission data in
- * persistent storage, or <tt>null</tt> if there is no permission data
- * in persistent storage.
- * @throws IOException If a failure occurs accessing peristent storage.
- */
- public synchronized String[] getLocations() throws IOException {
- int size = permissionFiles.size();
-
- if (size == 0) {
- return null;
- }
-
- String[] locations = new String[size];
-
- Enumeration keysEnum = permissionFiles.keys();
-
- for (int i = 0; i < size; i++) {
- locations[i] = (String) keysEnum.nextElement();
- }
-
- return locations;
- }
-
- /**
- * Gets the permission data assigned to the specified
- * location.
- *
- * @param location The location whose permission data is to
- * be returned.
- *
- * @return The permission data assigned to the specified
- * location, or <tt>null</tt> if that location has not been assigned any
- * permission data.
- * @throws IOException If a failure occurs accessing peristent storage.
- */
- public synchronized String[] getPermissionData(String location) throws IOException {
- File file;
-
- if (location == null) {
- file = defaultData;
- } else {
- file = (File) permissionFiles.get(location);
-
- if (file == null) {
- return null;
- }
- }
-
- try {
- return readData(file);
- } catch (FileNotFoundException e) {
- return null;
- }
- }
-
- /**
- * Assigns the specified permission data to the specified
- * location.
- *
- * @param location The location that will be assigned the
- * permissions.
- * @param data The permission data to be assigned, or <tt>null</tt>
- * if the specified location is to be removed from persistent storaqe.
- * @throws IOException If a failure occurs modifying peristent storage.
- */
- public synchronized void setPermissionData(String location, String[] data) throws IOException {
- File file;
-
- if (location == null) {
- file = defaultData;
-
- if (data == null) {
- ReliableFile.delete(defaultData);
- } else {
- save(defaultData, null, data); /* Save the value in persistent storage */
- }
- } else {
- file = (File) permissionFiles.get(location);
-
- if (data == null) {
- if (file == null) {
- return;
- }
-
- permissionFiles.remove(location);
-
- ReliableFile.delete(file);
- } else {
- file = save(file, location, data); /* Save the value in persistent storage */
-
- permissionFiles.put(location, file);
- }
- }
- }
-
- /**
- * Load the locations for which permission data exists.
- *
- * @throws IOException If an error occurs reading the files.
- */
- protected void loadLocations() throws IOException {
- String list[] = ReliableFile.getBaseFiles(permissionDir);
- if (list == null)
- return;
- int len = list.length;
-
- for (int i = 0; i < len; i++) {
- String name = list[i];
-
- if (name.endsWith(ReliableFile.tmpExt)) {
- continue;
- }
- if (name.equals(CONDPERMS)) {
- continue;
- }
-
- File file = new File(permissionDir, name);
-
- try {
- String location = readLocation(file);
-
- if (location != null) {
- permissionFiles.put(location, file);
- }
- } catch (FileNotFoundException e) {
- /* the file should have been there */
- }
- }
- }
-
- /**
- * Read the location from the specified file.
- *
- * @param file File to read the location from.
- * @return Location from the file or null if the file is unknown.
- * @throws IOException If an error occurs reading the file.
- * @throws FileNotFoundException if the data file does not exist.
- */
- private String readLocation(File file) throws IOException {
- DataInputStream in = new DataInputStream(new ReliableFileInputStream(file));
- try {
- int version = in.readInt();
-
- switch (version) {
- case PERMISSIONDATA_VERSION_1 : {
- boolean locationPresent = in.readBoolean();
-
- if (locationPresent) {
- String location = in.readUTF();
-
- return location;
- }
- break;
- }
- default : {
- throw new IOException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION);
- }
- }
- } finally {
- in.close();
- }
-
- return null;
- }
-
- /**
- * Read the permission data from the specified file.
- *
- * @param file File to read the permission data from.
- * @throws IOException If an error occurs reading the file.
- * @throws FileNotFoundException if the data file does not exist.
- */
- private String[] readData(File file) throws IOException {
- DataInputStream in = new DataInputStream(new ReliableFileInputStream(file));
- try {
- int version = in.readInt();
-
- switch (version) {
- case PERMISSIONDATA_VERSION_1 : {
- boolean locationPresent = in.readBoolean();
-
- if (locationPresent) {
- String location = in.readUTF();
- }
-
- int size = in.readInt();
- String[] data = new String[size];
-
- for (int i = 0; i < size; i++) {
- data[i] = in.readUTF();
- }
-
- return data;
- }
- default : {
- throw new IOException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION);
- }
- }
- } finally {
- in.close();
- }
- }
-
- /**
- * Save the permission data for the specified location.
- * This assumes an attempt has been made to load
- * the specified location just prior to calling save.
- */
- protected File save(File file, String location, String[] data) throws IOException {
- if (file == null) /* we need to create a filename */{
- file = File.createTempFile("perm", "", permissionDir); //$NON-NLS-1$ //$NON-NLS-2$
- file.delete(); /* delete the empty file */
- }
-
- int size = data.length;
-
- DataOutputStream out = new DataOutputStream(new ReliableFileOutputStream(file));
-
- try {
- out.writeInt(PERMISSIONDATA_VERSION);
- if (location == null) {
- out.writeBoolean(false);
- } else {
- out.writeBoolean(true);
- out.writeUTF(location);
- }
- out.writeInt(size);
-
- for (int i = 0; i < size; i++) {
- out.writeUTF(data[i]);
- }
-
- } finally {
- out.close();
- }
-
- return file;
- }
-
- public void saveConditionalPermissionInfos(String[] infos) throws IOException {
- BufferedWriter writer = null;
- try {
- writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(permissionDir, CONDPERMS))));
- if (infos == null)
- return;
- for (int i = 0; i < infos.length; i++) {
- writer.write(infos[i]);
- writer.newLine();
- }
- } finally {
- if (writer != null)
- writer.close();
- }
- }
-
- public String[] getConditionalPermissionInfos() throws IOException {
- BufferedReader reader = null;
- ArrayList results = new ArrayList(10);
- try {
- reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(permissionDir, CONDPERMS))));
- String line;
- while ((line = reader.readLine()) != null)
- if (line.length() != 0)
- results.add(line);
- } catch (FileNotFoundException e) {
- // do nothing return empty vector
- } catch (IOException e) {
- throw e;
- } catch (Exception e) {
- throw new IOException(e.getMessage());
- } finally {
- if (reader != null)
- reader.close();
- }
- return results.size() == 0 ? null : (String[]) results.toArray(new String[results.size()]);
- }
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultAdaptor.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultAdaptor.java
deleted file mode 100644
index 7d607c4a6..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultAdaptor.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.internal.defaultadaptor;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import org.eclipse.osgi.framework.adaptor.BundleData;
-import org.eclipse.osgi.framework.adaptor.core.*;
-import org.eclipse.osgi.framework.debug.Debug;
-import org.eclipse.osgi.framework.log.FrameworkLog;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.FrameworkEvent;
-
-/**
- * The DefaultAdaptor for the Framework. This adaptor uses
- * root bundle store directory on the local filesystem to
- * store bundle files and bundle data.
- * <p>
- * Each bundle installed in the Framework will have a unique
- * directory using the bundle ID as the name. Each bundles
- * unique directory has a generational directory a data directory
- * and a metadata file.
- * <p>
- * The generational directory is used to store the different
- * versions of the bundle that have been installed. Each time
- * the bundle is updated a new generational directory will be
- * created.
- * <p>
- * The data directory is used to create data file objects requested
- * by the bundle. This directory will not change when updating
- * a bundle
- * <p>
- * The metadata file contains persistent data about the bundle
- * (e.g. startlevel, persistent start state, etc)
- */
-public class DefaultAdaptor extends AbstractFrameworkAdaptor {
- public static final String METADATA_ADAPTOR_NEXTID = "METADATA_ADAPTOR_NEXTID"; //$NON-NLS-1$
- public static final String METADATA_ADAPTOR_IBSL = "METADATA_ADAPTOR_IBSL"; //$NON-NLS-1$
-
- public static final String METADATA_BUNDLE_GEN = "METADATA_BUNDLE_GEN"; //$NON-NLS-1$
- public static final String METADATA_BUNDLE_LOC = "METADATA_BUNDLE_LOC"; //$NON-NLS-1$
- public static final String METADATA_BUNDLE_REF = "METADATA_BUNDLE_REF"; //$NON-NLS-1$
- public static final String METADATA_BUNDLE_NAME = "METADATA_BUNDLE_NAME"; //$NON-NLS-1$
- public static final String METADATA_BUNDLE_NCP = "METADATA_BUNDLE_NCP"; //$NON-NLS-1$
- public static final String METADATA_BUNDLE_ABSL = "METADATA_BUNDLE_ABSL"; //$NON-NLS-1$
- public static final String METADATA_BUNDLE_STATUS = "METADATA_BUNDLE_STATUS"; //$NON-NLS-1$
- public static final String METADATA_BUNDLE_METADATA = "METADATA_BUNDLE_METADATA"; //$NON-NLS-1$
- public static final String METADATA_LAST_MODIFIED = "METADATA_LAST_MODIFIED"; //$NON-NLS-1$
-
- /**
- * The MetaData for the default adaptor
- */
- protected MetaData fwMetadata;
-
- public DefaultAdaptor(String[] args) {
- super(args);
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#getInstalledBundles()
- */
- public BundleData[] getInstalledBundles() {
- String list[] = getBundleStoreRootDir().list();
-
- if (list == null) {
- return null;
- }
- ArrayList bundleDatas = new ArrayList(list.length);
-
- /* create bundle objects for all installed bundles. */
- for (int i = 0; i < list.length; i++) {
- try {
- DefaultBundleData data;
-
- long id = -1;
- try {
- id = Long.parseLong(list[i]);
- } catch (NumberFormatException nfe) {
- continue;
- }
- data = (DefaultBundleData) getElementFactory().createBundleData(this, id);
- loadMetaDataFor(data);
- data.initializeExistingBundle();
-
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("BundleData created: " + data); //$NON-NLS-1$
- }
- processExtension(data, EXTENSION_INITIALIZE);
- bundleDatas.add(data);
- } catch (BundleException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to open Bundle[" + list[i] + "]: " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
- Debug.printStackTrace(e);
- }
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to open Bundle[" + list[i] + "]: " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
- Debug.printStackTrace(e);
- }
- }
- }
-
- return (BundleData[]) bundleDatas.toArray(new BundleData[bundleDatas.size()]);
- }
-
- public void setInitialBundleStartLevel(int value) {
- super.setInitialBundleStartLevel(value);
- try {
- persistInitialBundleStartLevel(value);
- } catch (IOException e) {
- eventPublisher.publishFrameworkEvent(FrameworkEvent.ERROR, context.getBundle(), e);
- }
- }
-
- protected void persistInitialBundleStartLevel(int value) throws IOException {
- fwMetadata.setInt(METADATA_ADAPTOR_IBSL, value);
- try {
- AccessController.doPrivileged(new PrivilegedExceptionAction() {
- public Object run() throws Exception {
- fwMetadata.save();
- return null;
- }
- });
- } catch (PrivilegedActionException e) {
- if (e.getException() instanceof IOException) {
- throw (IOException)e.getException();
- }
- throw (RuntimeException)e.getException();
- }
- }
-
- public AdaptorElementFactory getElementFactory() {
- if (elementFactory == null)
- elementFactory = new DefaultElementFactory();
- return elementFactory;
- }
-
- protected void loadMetaDataFor(DefaultBundleData data) throws IOException {
- MetaData bundleMetaData = (new MetaData(new File(data.getBundleStoreDir(), ".bundle"), "Bundle metadata")); //$NON-NLS-1$ //$NON-NLS-2$
- bundleMetaData.load();
-
- data.setLocation(bundleMetaData.get(METADATA_BUNDLE_LOC, null));
- data.setFileName(bundleMetaData.get(METADATA_BUNDLE_NAME, null));
- data.setGeneration(bundleMetaData.getInt(METADATA_BUNDLE_GEN, -1));
- data.setNativePaths(bundleMetaData.get(METADATA_BUNDLE_NCP, null));
- data.setStartLevel(bundleMetaData.getInt(METADATA_BUNDLE_ABSL, 1));
- data.setStatus(bundleMetaData.getInt(METADATA_BUNDLE_STATUS, 0));
- data.setReference(bundleMetaData.getBoolean(METADATA_BUNDLE_REF, false));
- data.setLastModified(bundleMetaData.getLong(METADATA_LAST_MODIFIED, 0));
-
- if (data.getGeneration() == -1 || data.getFileName() == null || data.getLocation() == null) {
- throw new IOException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION);
- }
- }
-
- public void saveMetaDataFor(AbstractBundleData data) throws IOException {
- MetaData bundleMetadata = (new MetaData(new File(((DefaultBundleData) data).createBundleStoreDir(), ".bundle"), "Bundle metadata")); //$NON-NLS-1$ //$NON-NLS-2$
- bundleMetadata.load();
-
- bundleMetadata.set(METADATA_BUNDLE_LOC, data.getLocation());
- bundleMetadata.set(METADATA_BUNDLE_NAME, data.getFileName());
- bundleMetadata.setInt(METADATA_BUNDLE_GEN, data.getGeneration());
- String nativePaths = data.getNativePathsString();
- if (nativePaths != null) {
- bundleMetadata.set(METADATA_BUNDLE_NCP, nativePaths);
- }
- bundleMetadata.setInt(METADATA_BUNDLE_ABSL, data.getStartLevel());
- bundleMetadata.setInt(METADATA_BUNDLE_STATUS, data.getStatus());
- bundleMetadata.setBoolean(METADATA_BUNDLE_REF, data.isReference());
- bundleMetadata.setLong(METADATA_LAST_MODIFIED, data.getLastModified());
-
- bundleMetadata.save();
- }
-
- protected void persistNextBundleID(long id) throws IOException {
- fwMetadata.setLong(METADATA_ADAPTOR_NEXTID, nextId);
- fwMetadata.save();
- }
-
- protected void initializeMetadata() throws IOException {
- fwMetadata = new MetaData(getMetaDataFile(), "Framework metadata"); //$NON-NLS-1$
- fwMetadata.load();
- nextId = fwMetadata.getLong(METADATA_ADAPTOR_NEXTID, 1);
- initialBundleStartLevel = fwMetadata.getInt(METADATA_ADAPTOR_IBSL, 1);
- }
-
- protected FrameworkLog createFrameworkLog() {
- return new DefaultLog();
- }
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultBundleData.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultBundleData.java
deleted file mode 100644
index c88eb3b12..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultBundleData.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.internal.defaultadaptor;
-
-import java.io.File;
-import java.io.IOException;
-import org.eclipse.osgi.framework.adaptor.core.AbstractBundleData;
-import org.eclipse.osgi.framework.debug.Debug;
-import org.osgi.framework.BundleException;
-
-/**
- * The <code>BundleData</code> represents a single bundle that is persistently
- * stored by a <code>FrameworkAdaptor</code>. A <code>BundleData</code> creates
- * the ClassLoader for a bundle, finds native libraries installed in the
- * FrameworkAdaptor for the bundle, creates data files for the bundle,
- * used to access bundle entries, manifest information, and getting and saving
- * metadata.
- *
- */
-public class DefaultBundleData extends AbstractBundleData {
- /**
- * Read data from an existing directory.
- * This constructor is used by getInstalledBundles.
- *
- * @throws NumberFormatException if the directory is not a
- * number, the directory contains a ".delete" file or
- * the directory does not contain a ".bundle" file.
- * @throws IOException If an error occurs initializing the bundle data.
- */
- public void initializeExistingBundle() throws BundleException, IOException {
- File delete = new File(getBundleStoreDir(), ".delete"); //$NON-NLS-1$
-
- /* and the directory is not marked for delete */
- if (delete.exists())
- throw new IOException();
-
- createBaseBundleFile();
-
- loadFromManifest();
- }
-
- /**
- * Constructs a DefaultBundleData for the DefaultAdaptor.
- *
- * @param adaptor the DefaultAdaptor for this DefaultBundleData
- * @param id the Bundle ID for this DefaultBundleData
- */
- public DefaultBundleData(DefaultAdaptor adaptor, long id) {
- super(adaptor, id);
- }
-
- public String toString() {
- return getLocation();
- }
-
- /**
- * Save the bundle data in the data file.
- *
- * @throws IOException if a write error occurs.
- */
- public synchronized void save() throws IOException {
- if (adaptor.canWrite())
- ((DefaultAdaptor) adaptor).saveMetaDataFor(this);
- }
-
- /**
- * Return the top level bundle directory.
- *
- * @return Top level bundle directory.
- */
- protected File createBundleStoreDir() {
- if (!getBundleStoreDir().exists() && !getBundleStoreDir().mkdirs()) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Unable to create bundle store directory: " + getBundleStoreDir().getPath()); //$NON-NLS-1$
- }
- }
- return getBundleStoreDir();
- }
-
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultElementFactory.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultElementFactory.java
deleted file mode 100644
index 87644a6b4..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultElementFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.osgi.framework.internal.defaultadaptor;
-
-import java.io.IOException;
-
-import org.eclipse.osgi.framework.adaptor.BundleProtectionDomain;
-import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
-import org.eclipse.osgi.framework.adaptor.core.*;
-
-public class DefaultElementFactory implements AdaptorElementFactory {
-
- public AbstractBundleData createBundleData(AbstractFrameworkAdaptor adaptor, long id) throws IOException {
- return new DefaultBundleData((DefaultAdaptor) adaptor, id);
- }
-
- public org.eclipse.osgi.framework.adaptor.BundleClassLoader createClassLoader(ClassLoaderDelegate delegate, BundleProtectionDomain domain, String[] bundleclasspath, AbstractBundleData data) {
- return new DefaultClassLoader(delegate, domain, bundleclasspath, data.getAdaptor().getBundleClassLoaderParent(), data);
- }
-
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultLog.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultLog.java
deleted file mode 100644
index dd1d027aa..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/DefaultLog.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.internal.defaultadaptor;
-
-import java.io.*;
-import org.eclipse.osgi.framework.log.FrameworkLog;
-import org.eclipse.osgi.framework.log.FrameworkLogEntry;
-import org.osgi.framework.FrameworkEvent;
-
-/*
- * This is an empty implementation that does no actually logging.
- */
-public class DefaultLog implements FrameworkLog {
-
- public DefaultLog() {
- }
-
- public void log(FrameworkEvent frameworkEvent) {
- }
-
- public void log(FrameworkLogEntry logEntry) {
- }
-
- public void setWriter(Writer newWriter, boolean append) {
- }
-
- public void setFile(File newFile, boolean append) throws IOException {
- }
-
- public File getFile() {
- return null;
- }
-
- public void setConsoleLog(boolean consoleLog) {
- }
-
- public void close() {
- }
-
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/MetaData.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/MetaData.java
deleted file mode 100644
index 60dee03dc..000000000
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/defaultadaptor/MetaData.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.internal.defaultadaptor;
-
-import java.io.*;
-import java.util.Properties;
-
-/**
- * This class uses a Properties object to store and get MetaData information.
- * All data is converted into String data before saving.
- */
-public class MetaData {
-
- /**
- * The Properties file to store the data.
- */
- Properties properties = new Properties();
-
- /**
- * The File object to store and load the Properties object.
- */
- File datafile;
-
- /**
- * The header string to use when storing data to the datafile.
- */
- String header;
-
- /**
- * Constructs a MetaData object that uses the datafile to persistently
- * store data.
- * @param datafile The File object used to persistently load and store data.
- * @param header The header to use when storing data persistently.
- */
- public MetaData(File datafile, String header) {
- this.datafile = datafile;
- this.header = header;
- }
-
- /**
- * Gets the metadata value for the key.
- * @param key the key of the metadata
- * @param def the default value to return if the key does not exist
- * @return the value of the metadata or null if the key does not exist
- * and the specified default is null.
- */
- public String get(String key, String def) {
- return properties.getProperty(key, def);
- }
-
- /**
- * Gets the integer value for the key.
- * @param key the key of the metadata
- * @param def the default value to return if the key does not exist
- * @return the value of the metadata; if the key does not exist or
- * the value cannot be converted to an int value then the
- * specified default value is returned.
- */
- public int getInt(String key, int def) {
- String result = get(key, null);
- if (result == null) {
- return def;
- }
- try {
- return Integer.parseInt(result);
- } catch (NumberFormatException nfe) {
- return def;
- }
- }
-
- /**
- * Gets the long value for the key.
- * @param key the key of the metadata
- * @param def the default value to return if the key does not exist
- * @return the value of the metadata; if the key does not exist or
- * the value cannot be converted to an long value then the
- * specified default value is returned.
- */
- public long getLong(String key, long def) {
- String result = get(key, null);
- if (result == null) {
- return def;
- }
- try {
- return Long.parseLong(result);
- } catch (NumberFormatException nfe) {
- return def;
- }
- }
-
- /**
- * Gets the boolean value for the key.
- * @param key the key of the metadata
- * @param def the default value to return if the key does not exist
- * @return the value of the metadata; if the key does not exist then the
- * specified default value is returned.
- */
- public boolean getBoolean(String key, boolean def) {
- String result = get(key, null);
- if (result == null) {
- return def;
- }
- return Boolean.valueOf(result).booleanValue();
- }
-
- /**
- * Sets the String value for a key.
- * @param key the key of the metadata
- * @param val the value of the metadata
- */
- public void set(String key, String val) {
- properties.put(key, val);
- }
-
- /**
- * Sets the int value for a key.
- * @param key the key of the metadata
- * @param val the value of the metadata
- */
- public void setInt(String key, int val) {
- properties.put(key, Integer.toString(val));
- }
-
- /**
- * Sets the long value for a key.
- * @param key the key of the metadata
- * @param val the value of the metadata
- */
- public void setLong(String key, long val) {
- properties.put(key, Long.toString(val));
- }
-
- /**
- * Sets the boolean value for a key.
- * @param key the key of the metadata
- * @param val the value of the metadata
- */
- public void setBoolean(String key, boolean val) {
- properties.put(key, (val ? Boolean.TRUE : Boolean.FALSE).toString());
- }
-
- /**
- * Removes the metadata value with the specified key.
- * @param key the key of the metadata to be removed
- */
- public void remove(String key) {
- properties.remove(key);
- }
-
- /**
- * Saves the metadata to persistent storage.
- * @throws IOException if there is a problem saving to persistent storage.
- */
- public void save() throws IOException {
- if (!datafile.exists() && datafile.getParent() != null) {
- File parent = new File(datafile.getParent());
- if (!parent.exists())
- parent.mkdir();
- }
-
- FileOutputStream fos = new FileOutputStream(datafile);
- try {
- properties.store(fos, header);
- } finally {
- fos.close();
- }
- }
-
- /**
- * Loads the metadata from persistent storage
- * @throws IOException if there is a problem reading from persistent storage.
- */
- public void load() throws IOException {
- properties.clear();
- if (datafile.exists()) {
- FileInputStream fis = new FileInputStream(datafile);
- try {
- properties.load(fis);
- } finally {
- fis.close();
- }
- }
- }
-
- /**
- * @see Object#toString()
- */
- public String toString() {
- return properties.toString();
- }
-
-}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/protocol/bundleentry/Handler.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/protocol/bundleentry/Handler.java
index 2bf25fbc3..61c09995e 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/protocol/bundleentry/Handler.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/protocol/bundleentry/Handler.java
@@ -14,9 +14,9 @@ package org.eclipse.osgi.framework.internal.protocol.bundleentry;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
-import org.eclipse.osgi.framework.adaptor.core.*;
-import org.eclipse.osgi.framework.internal.core.AbstractBundle;
-import org.eclipse.osgi.framework.internal.core.BundleResourceHandler;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.framework.internal.core.*;
/**
* URLStreamHandler the bundleentry protocol.
@@ -36,8 +36,8 @@ public class Handler extends BundleResourceHandler {
}
protected BundleEntry findBundleEntry(URL url, AbstractBundle bundle) throws IOException {
- AbstractBundleData bundleData = (AbstractBundleData) bundle.getBundleData();
- BundleEntry entry = bundleData.getBaseBundleFile().getEntry(url.getPath());
+ BaseData bundleData = (BaseData) bundle.getBundleData();
+ BundleEntry entry = bundleData.getBundleFile().getEntry(url.getPath());
if (entry == null)
throw new FileNotFoundException(url.getPath());
return entry;
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/protocol/bundleresource/Handler.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/protocol/bundleresource/Handler.java
index af29b5743..1c0b64c45 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/protocol/bundleresource/Handler.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/protocol/bundleresource/Handler.java
@@ -15,10 +15,11 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
-import org.eclipse.osgi.framework.adaptor.core.*;
-import org.eclipse.osgi.framework.adaptor.core.BundleEntry;
-import org.eclipse.osgi.framework.internal.core.*;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
+import org.eclipse.osgi.baseadaptor.loader.ClasspathManager;
import org.eclipse.osgi.framework.internal.core.AbstractBundle;
+import org.eclipse.osgi.framework.internal.core.BundleResourceHandler;
/**
* URLStreamHandler the bundleresource protocol.
@@ -38,16 +39,16 @@ public class Handler extends BundleResourceHandler {
}
protected BundleEntry findBundleEntry(URL url, AbstractBundle bundle) throws IOException {
- AbstractClassLoader cl = (AbstractClassLoader) getBundleClassLoader(bundle);
- if (cl== null)
+ BaseClassLoader classloader = getBundleClassLoader(bundle);
+ if (classloader == null)
throw new FileNotFoundException(url.getPath());
+ ClasspathManager cpManager = classloader.getClasspathManager();
int index = url.getPort();
BundleEntry entry = null;
if (index == 0) {
- entry = (BundleEntry) cl.findLocalObject(url.getPath());
- }
- else {
- Enumeration entries = cl.findLocalObjects(url.getPath());
+ entry = cpManager.findLocalEntry(url.getPath());
+ } else {
+ Enumeration entries = cpManager.findLocalEntries(url.getPath());
if (entries != null)
for (int i = 0; entries.hasMoreElements() && i <= index; i++)
entry = (BundleEntry) entries.nextElement();
@@ -58,4 +59,3 @@ public class Handler extends BundleResourceHandler {
}
}
-
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFile.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFile.java
index a03cc3e83..0321479b0 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFile.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFile.java
@@ -501,6 +501,7 @@ public class ReliableFile {
* Answers a boolean indicating whether or not the specified reliable file
* exists on the underlying file system. This call only returns if a file
* exists and not if the file contents are valid.
+ * @param file returns true if the specified reliable file exists; otherwise false is returned
*
* @return <code>true</code> if the specified reliable file exists,
* <code>false</code> otherwise.
@@ -573,6 +574,7 @@ public class ReliableFile {
/**
* Delete the specified reliable file on the underlying file system.
+ * @param deleteFile the reliable file to delete
*
* @return <code>true</code> if the specified reliable file was deleted,
* <code>false</code> otherwise.
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileInputStream.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileInputStream.java
index c817fda06..e1dffe8a4 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileInputStream.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileInputStream.java
@@ -120,6 +120,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default FilterInputStream method.
+ * @see FilterInputStream#read(byte[], int, int)
*/
public synchronized int read(byte b[], int off, int len) throws IOException {
if (readPos >= length) {
@@ -138,6 +139,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default FilterInputStream method.
+ * @see FilterInputStream#read(byte[])
*/
public synchronized int read(byte b[]) throws IOException {
return read(b, 0, b.length);
@@ -145,6 +147,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default FilterInputStream method.
+ * @see FilterInputStream#read()
*/
public synchronized int read() throws IOException {
if (readPos >= length) {
@@ -160,6 +163,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default available method.
+ * @see FilterInputStream#available()
*/
public synchronized int available() throws IOException {
if (readPos < length) // just in case
@@ -169,6 +173,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default skip method.
+ * @see FilterInputStream#skip(long)
*/
public synchronized long skip(long n) throws IOException {
long len = super.skip(n);
@@ -180,6 +185,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default markSupported method.
+ * @see FilterInputStream#markSupported()
*/
public boolean markSupported() {
return false;
@@ -187,6 +193,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default mark method.
+ * @see FilterInputStream#mark(int)
*/
public void mark(int readlimit) {
//ignore
@@ -194,6 +201,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default reset method.
+ * @see FilterInputStream#reset()
*/
public void reset() throws IOException {
throw new IOException("reset not supported."); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileOutputStream.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileOutputStream.java
index a67f88f54..3c2a3a099 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileOutputStream.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileOutputStream.java
@@ -142,6 +142,7 @@ public class ReliableFileOutputStream extends FilterOutputStream {
/**
* Override default FilterOutputStream method.
+ * @see FilterOutputStream#write(byte[])
*/
public void write(byte[] b) throws IOException {
this.write(b, 0, b.length);
@@ -149,6 +150,7 @@ public class ReliableFileOutputStream extends FilterOutputStream {
/**
* Override default FilterOutputStream method.
+ * @see FilterOutputStream#write(byte[], int, int)
*/
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
@@ -157,6 +159,7 @@ public class ReliableFileOutputStream extends FilterOutputStream {
/**
* Override default FilterOutputStream method.
+ * @see FilterOutputStream#write(int)
*/
public void write(int b) throws IOException {
out.write(b);
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AdaptorMsg.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorMsg.java
index d5a71a06f..a2c519ecb 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/AdaptorMsg.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorMsg.java
@@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
-package org.eclipse.osgi.framework.adaptor.core;
+package org.eclipse.osgi.internal.baseadaptor;
import org.eclipse.osgi.util.NLS;
@@ -49,7 +49,7 @@ public class AdaptorMsg extends NLS {
public static String URL_NO_BUNDLE_FOUND;
public static String URL_NO_BUNDLE_ID;
- private static final String BUNDLE_NAME = "org.eclipse.osgi.framework.adaptor.core.ExternalMessages"; //$NON-NLS-1$
+ private static final String BUNDLE_NAME = "org.eclipse.osgi.internal.baseadaptor.ExternalMessages"; //$NON-NLS-1$
static {
// initialize resource bundles
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorUtil.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorUtil.java
new file mode 100644
index 000000000..0c6f89c85
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorUtil.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.baseadaptor;
+
+import java.io.*;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import org.eclipse.core.runtime.internal.adaptor.EclipseAdaptorMsg;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.framework.util.Headers;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.*;
+
+/**
+ * A utility class with some generally useful static methods for adaptor hook implementations
+ */
+public class AdaptorUtil {
+ /** The NULL tag used in bundle storage */
+ public static final byte NULL = 0;
+ /** The OBJECT tag used in bundle storage */
+ public static final byte OBJECT = 1;
+
+ /**
+ * Does a recursive copy of one directory to another.
+ * @param inDir input directory to copy.
+ * @param outDir output directory to copy to.
+ * @throws IOException if any error occurs during the copy.
+ */
+ public static void copyDir(File inDir, File outDir) throws IOException {
+ String[] files = inDir.list();
+ if (files != null && files.length > 0) {
+ outDir.mkdir();
+ for (int i = 0; i < files.length; i++) {
+ File inFile = new File(inDir, files[i]);
+ File outFile = new File(outDir, files[i]);
+ if (inFile.isDirectory()) {
+ copyDir(inFile, outFile);
+ } else {
+ InputStream in = new FileInputStream(inFile);
+ readFile(in, outFile);
+ }
+ }
+ }
+ }
+
+ /**
+ * Read a file from an InputStream and write it to the file system.
+ *
+ * @param in InputStream from which to read.
+ * @param file output file to create.
+ * @exception IOException
+ */
+ public static void readFile(InputStream in, File file) throws IOException {
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(file);
+
+ byte buffer[] = new byte[1024];
+ int count;
+ while ((count = in.read(buffer, 0, buffer.length)) > 0) {
+ fos.write(buffer, 0, count);
+ }
+
+ fos.close();
+ fos = null;
+
+ in.close();
+ in = null;
+ } catch (IOException e) {
+ // close open streams
+ if (fos != null) {
+ try {
+ fos.close();
+ } catch (IOException ee) {
+ // nothing to do here
+ }
+ }
+
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException ee) {
+ // nothing to do here
+ }
+ }
+
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
+ Debug.println("Unable to read file"); //$NON-NLS-1$
+ Debug.printStackTrace(e);
+ }
+
+ throw e;
+ }
+ }
+
+ /**
+ * This function performs the equivalent of "rm -r" on a file or directory.
+ *
+ * @param file file or directory to delete
+ * @return false is the specified files still exists, true otherwise.
+ */
+ public static boolean rm(File file) {
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ String list[] = file.list();
+ if (list != null) {
+ int len = list.length;
+ for (int i = 0; i < len; i++) {
+ // we are doing a lot of garbage collecting here
+ rm(new File(file, list[i]));
+ }
+ }
+ }
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
+ if (file.isDirectory()) {
+ Debug.println("rmdir " + file.getPath()); //$NON-NLS-1$
+ } else {
+ Debug.println("rm " + file.getPath()); //$NON-NLS-1$
+ }
+ }
+
+ boolean success = file.delete();
+
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
+ if (!success) {
+ Debug.println(" rm failed!!"); //$NON-NLS-1$
+ }
+ }
+
+ return (success);
+ }
+ return (true);
+ }
+
+ public static String readString(DataInputStream in, boolean intern) throws IOException {
+ byte type = in.readByte();
+ if (type == NULL)
+ return null;
+ return intern ? in.readUTF().intern() : in.readUTF();
+ }
+
+ public static void writeStringOrNull(DataOutputStream out, String string) throws IOException {
+ if (string == null)
+ out.writeByte(NULL);
+ else {
+ out.writeByte(OBJECT);
+ out.writeUTF(string);
+ }
+ }
+
+ public static Version loadVersion(DataInputStream in) throws IOException {
+ String versionString = readString(in, false);
+ try {
+ return Version.parseVersion(versionString);
+ } catch (IllegalArgumentException e) {
+ return new InvalidVersion(versionString);
+ }
+ }
+
+ /**
+ * Register a service object.
+ * @param name the service class name
+ * @param service the service object
+ * @param context the registering bundle context
+ * @return the service registration object
+ */
+ public static ServiceRegistration register(String name, Object service, BundleContext context) {
+ Hashtable properties = new Hashtable(7);
+ Dictionary headers = context.getBundle().getHeaders();
+ properties.put(Constants.SERVICE_VENDOR, headers.get(Constants.BUNDLE_VENDOR));
+ properties.put(Constants.SERVICE_RANKING, new Integer(Integer.MAX_VALUE));
+ properties.put(Constants.SERVICE_PID, context.getBundle().getBundleId() + "." + service.getClass().getName()); //$NON-NLS-1$
+ return context.registerService(name, service, properties);
+ }
+
+ public static Dictionary loadManifestFrom(BaseData bundledata) throws BundleException {
+ URL url = bundledata.getEntry(Constants.OSGI_BUNDLE_MANIFEST);
+ if (url == null)
+ return null;
+ try {
+ return Headers.parseManifest(url.openStream());
+ } catch (IOException e) {
+ throw new BundleException(NLS.bind(EclipseAdaptorMsg.ECLIPSE_DATA_ERROR_READING_MANIFEST, bundledata.getLocation()), e);
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseClassLoadingHook.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseClassLoadingHook.java
new file mode 100644
index 000000000..d752d20af
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseClassLoadingHook.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.baseadaptor;
+
+import java.io.File;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook;
+import org.eclipse.osgi.baseadaptor.loader.*;
+import org.eclipse.osgi.framework.adaptor.BundleProtectionDomain;
+import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
+import org.eclipse.osgi.framework.debug.Debug;
+
+public class BaseClassLoadingHook implements ClassLoadingHook {
+
+ public String findLibrary(BaseData data, String libName) {
+ String mappedName = System.mapLibraryName(libName);
+ String path = null;
+ if (Debug.DEBUG && Debug.DEBUG_LOADER)
+ Debug.println(" mapped library name: " + mappedName); //$NON-NLS-1$
+ path = findNativePath(data, mappedName);
+ if (path == null) {
+ if (Debug.DEBUG && Debug.DEBUG_LOADER)
+ Debug.println(" library does not exist: " + mappedName); //$NON-NLS-1$
+ path = findNativePath(data, libName);
+ }
+ if (Debug.DEBUG && Debug.DEBUG_LOADER)
+ Debug.println(" returning library: " + path); //$NON-NLS-1$
+ return path;
+ }
+
+ private String findNativePath(BaseData bundledata, String libname) {
+ int slash = libname.lastIndexOf('/');
+ if (slash >= 0)
+ libname = libname.substring(slash + 1);
+ String[] nativepaths = getNativePaths(bundledata);
+ if (nativepaths == null)
+ return null;
+ for (int i = 0; i < nativepaths.length; i++) {
+ slash = nativepaths[i].lastIndexOf('/');
+ String path = slash < 0 ? nativepaths[i] : nativepaths[i].substring(slash + 1);
+ if (path.equals(libname)) {
+ File nativeFile = bundledata.getBundleFile().getFile(nativepaths[i], true);
+ if (nativeFile != null)
+ return nativeFile.getAbsolutePath();
+ }
+ }
+ return null;
+ }
+
+ private String[] getNativePaths(BaseData bundledata) {
+ BaseStorageHook storageHook = (BaseStorageHook) bundledata.getStorageHook(BaseStorageHook.KEY);
+ return storageHook != null ? storageHook.getNativePaths() : null;
+ }
+
+ public boolean addClassPathEntry(ArrayList cpEntries, String cp, ClasspathManager hostmanager, BaseData sourcedata, ProtectionDomain sourcedomain) {
+ // do nothing
+ return false;
+ }
+
+ public ClassLoader getBundleClassLoaderParent() {
+ // do nothing
+ return null;
+ }
+
+ public byte[] processClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
+ // do nothing
+ return null;
+ }
+
+ public BaseClassLoader createClassLoader(ClassLoader parent, ClassLoaderDelegate delegate, BundleProtectionDomain domain, BaseData data, String[] bundleclasspath) {
+ // do nothing
+ return null;
+ }
+
+ public void initializedClassLoader(BaseClassLoader baseClassLoader, BaseData data) {
+ // do nothing
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseHookConfigurator.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseHookConfigurator.java
new file mode 100644
index 000000000..abcc816fd
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseHookConfigurator.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.baseadaptor;
+
+import org.eclipse.osgi.baseadaptor.HookConfigurator;
+import org.eclipse.osgi.baseadaptor.HookRegistry;
+
+/**
+ * Add the hooks necessary to support the OSGi Framework specification.
+ */
+public class BaseHookConfigurator implements HookConfigurator {
+
+ public void addHooks(HookRegistry registry) {
+ // always add the BaseStorageHook and BaseClassLoadingHook; it is required for the storage implementation
+ registry.addStorageHook(new BaseStorageHook(BaseStorage.getInstance()));
+ registry.addClassLoadingHook(new BaseClassLoadingHook());
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BasePermissionStorage.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BasePermissionStorage.java
new file mode 100644
index 000000000..c0deb55c1
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BasePermissionStorage.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.baseadaptor;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import org.eclipse.osgi.framework.adaptor.PermissionStorage;
+
+public class BasePermissionStorage implements PermissionStorage {
+
+ private HashMap locations = new HashMap();
+ private String[] defaultInfos;
+ private String[] condPermInfos;
+ private BaseStorage storage;
+ private boolean dirty;
+
+ BasePermissionStorage(BaseStorage storage) {
+ this.storage = storage;
+ }
+
+ public String[] getLocations() throws IOException {
+ synchronized (locations) {
+ String[] result = new String[locations.size()];
+ int i = 0;
+ for (Iterator iLocs = locations.keySet().iterator(); iLocs.hasNext(); i++)
+ result[i] = (String) iLocs.next();
+ return result;
+ }
+ }
+
+ public String[] getPermissionData(String location) throws IOException {
+ if (location == null)
+ return defaultInfos;
+ synchronized (locations) {
+ if (locations.size() == 0)
+ return null;
+ return (String[]) locations.get(location);
+ }
+ }
+
+ public void setPermissionData(String location, String[] data) throws IOException {
+ if (location == null) {
+ defaultInfos = data;
+ return;
+ }
+ synchronized (locations) {
+ if (data == null)
+ locations.remove(location);
+ else
+ locations.put(location, data);
+ }
+ setDirty(true);
+ storage.requestSave();
+ }
+
+ public void saveConditionalPermissionInfos(String[] infos) throws IOException {
+ condPermInfos = infos;
+ setDirty(true);
+ storage.requestSave();
+ }
+
+ public String[] getConditionalPermissionInfos() throws IOException {
+ return condPermInfos;
+ }
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java
new file mode 100644
index 000000000..814c556f9
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java
@@ -0,0 +1,1111 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.baseadaptor;
+
+import java.io.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.*;
+import java.util.*;
+import org.eclipse.core.runtime.adaptor.EclipseStarter;
+import org.eclipse.core.runtime.adaptor.LocationManager;
+import org.eclipse.core.runtime.internal.adaptor.EclipseAdaptorMsg;
+import org.eclipse.osgi.baseadaptor.BaseAdaptor;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.bundlefile.*;
+import org.eclipse.osgi.baseadaptor.hooks.BundleFileFactoryHook;
+import org.eclipse.osgi.baseadaptor.hooks.StorageHook;
+import org.eclipse.osgi.framework.adaptor.*;
+import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.framework.debug.FrameworkDebugOptions;
+import org.eclipse.osgi.framework.internal.core.*;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.framework.log.FrameworkLogEntry;
+import org.eclipse.osgi.framework.util.KeyedHashSet;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.eclipse.osgi.service.resolver.*;
+import org.eclipse.osgi.storagemanager.ManagedOutputStream;
+import org.eclipse.osgi.storagemanager.StorageManager;
+import org.eclipse.osgi.util.ManifestElement;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.*;
+
+public class BaseStorage {
+ private static final String RUNTIME_ADAPTOR = FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + "/eclipseadaptor"; //$NON-NLS-1$
+ private static final String OPTION_PLATFORM_ADMIN = RUNTIME_ADAPTOR + "/debug/platformadmin"; //$NON-NLS-1$
+ private static final String OPTION_PLATFORM_ADMIN_RESOLVER = RUNTIME_ADAPTOR + "/debug/platformadmin/resolver"; //$NON-NLS-1$
+ private static final String OPTION_MONITOR_PLATFORM_ADMIN = RUNTIME_ADAPTOR + "/resolver/timing"; //$NON-NLS-1$
+ private static final String OPTION_RESOLVER_READER = RUNTIME_ADAPTOR + "/resolver/reader/timing"; //$NON-NLS-1$
+ private static final String PROP_FRAMEWORK_EXTENSIONS = "osgi.framework.extensions"; //$NON-NLS-1$
+ private static final String PROP_BUNDLE_STORE = "osgi.bundlestore"; //$NON-NLS-1$
+ // The name of the bundle data directory
+ static final String DATA_DIR_NAME = "data"; //$NON-NLS-1$
+ // System property used to determine whether State saver needs to be enabled
+ private static final String PROP_ENABLE_STATE_SAVER = "eclipse.enableStateSaver"; //$NON-NLS-1$
+ static final String BUNDLEFILE_NAME = "bundlefile"; //$NON-NLS-1$
+ // System property used to clean the osgi configuration area
+ private static final String PROP_CLEAN = "osgi.clean"; //$NON-NLS-1$
+
+ /** The current bundle data version */
+ public static final byte BUNDLEDATA_VERSION = 18;
+ /**
+ * flag to indicate a framework extension is being intialized
+ */
+ public static final byte EXTENSION_INITIALIZE = 0x01;
+ /**
+ * flag to indicate a framework extension is being installed
+ */
+ public static final byte EXTENSION_INSTALLED = 0x02;
+ /**
+ * flag to indicate a framework extension is being uninstalled
+ */
+ public static final byte EXTENSION_UNINSTALLED = 0x04;
+ /**
+ * flag to indicate a framework extension is being updated
+ */
+ public static final byte EXTENSION_UPDATED = 0x08;
+ private static final String PERM_DATA_FILE = ".permdata"; //$NON-NLS-1$
+ private static final byte PERMDATA_VERSION = 1;
+
+ private static final BaseStorage INSTANCE = new BaseStorage();
+
+ private BaseAdaptor adaptor;
+ // assume a file: installURL
+ private String installPath;
+ private StorageManager storageManager;
+ private StateManager stateManager;
+ // no need to synchronize on storageHooks because the elements are statically set in initialize
+ private KeyedHashSet storageHooks = new KeyedHashSet(5, false);
+ private BundleContext context;
+ /**
+ * The add URL method used to support framework extensions
+ */
+ private Method addURLMethod;
+ /**
+ * The list of configured framework extensions
+ */
+ private String[] configuredExtensions;
+
+ private long timeStamp = 0;
+ private int initialBundleStartLevel = 1;
+ private long nextId = 1;
+ /**
+ * directory containing installed bundles
+ */
+ private File bundleStoreRoot;
+
+ private BasePermissionStorage permissionStorage;
+ private StateSaver stateSaver;
+ private boolean invalidState;
+
+ private BaseStorage() {
+ // make constructor private
+ }
+
+ public void initialize(BaseAdaptor adaptor) throws IOException {
+ this.adaptor = adaptor;
+ setDebugOptions();
+ if (Boolean.valueOf(FrameworkProperties.getProperty(BaseStorage.PROP_CLEAN)).booleanValue())
+ cleanOSGiCache();
+ // initialize the addURLMethod to support framework extensions
+ ClassLoader fwloader = BaseStorage.class.getClassLoader();
+ if (fwloader != null)
+ addURLMethod = findaddURLMethod(fwloader.getClass());
+ // we need to set the install path as soon as possible so we can determine
+ // the absolute location of install relative URLs
+ Location installLoc = LocationManager.getInstallLocation();
+ if (installLoc != null) {
+ URL installURL = installLoc.getURL();
+ // assume install URL is file: based
+ installPath = installURL.getPath();
+ }
+ boolean readOnlyConfiguration = LocationManager.getConfigurationLocation().isReadOnly();
+ storageManager = initFileManager(LocationManager.getOSGiConfigurationDir(), readOnlyConfiguration ? "none" : null, readOnlyConfiguration); //$NON-NLS-1$
+ // initialize the storageHooks
+ StorageHook[] hooks = adaptor.getHookRegistry().getStorageHooks();
+ for (int i = 0; i < hooks.length; i++)
+ storageHooks.add(hooks[i]);
+ }
+
+ private void setDebugOptions() {
+ FrameworkDebugOptions options = FrameworkDebugOptions.getDefault();
+ // may be null if debugging is not enabled
+ if (options == null)
+ return;
+ StateManager.DEBUG = options != null;
+ StateManager.DEBUG_READER = options.getBooleanOption(OPTION_RESOLVER_READER, false);
+ StateManager.MONITOR_PLATFORM_ADMIN = options.getBooleanOption(OPTION_MONITOR_PLATFORM_ADMIN, false);
+ StateManager.DEBUG_PLATFORM_ADMIN = options.getBooleanOption(OPTION_PLATFORM_ADMIN, false);
+ StateManager.DEBUG_PLATFORM_ADMIN_RESOLVER = options.getBooleanOption(OPTION_PLATFORM_ADMIN_RESOLVER, false);
+ }
+
+ protected StorageManager initFileManager(File baseDir, String lockMode, boolean readOnly) {
+ StorageManager sManager = new StorageManager(baseDir, lockMode, readOnly);
+ try {
+ sManager.open(!readOnly);
+ } catch (IOException ex) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
+ Debug.println("Error reading framework metadata: " + ex.getMessage()); //$NON-NLS-1$
+ Debug.printStackTrace(ex);
+ }
+ String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_FILEMANAGER_OPEN_ERROR, ex.getMessage());
+ FrameworkLogEntry logEntry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, ex, null);
+ adaptor.getFrameworkLog().log(logEntry);
+ }
+ return sManager;
+ }
+
+ public boolean isReadOnly() {
+ return storageManager.isReadOnly();
+ }
+
+ public void compact() throws IOException {
+ if (!isReadOnly())
+ compact(getBundleStoreRoot());
+ }
+
+ private void compact(File directory) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("compact(" + directory.getPath() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ String list[] = directory.list();
+ if (list == null)
+ return;
+
+ int len = list.length;
+ for (int i = 0; i < len; i++) {
+ if (BaseStorage.DATA_DIR_NAME.equals(list[i]))
+ continue; /* do not examine the bundles data dir. */
+ File target = new File(directory, list[i]);
+ // if the file is a directory
+ if (!target.isDirectory())
+ continue;
+ File delete = new File(target, ".delete"); //$NON-NLS-1$
+ // and the directory is marked for delete
+ if (delete.exists()) {
+ // if rm fails to delete the directory and .delete was removed
+ if (!AdaptorUtil.rm(target) && !delete.exists()) {
+ try {
+ // recreate .delete
+ FileOutputStream out = new FileOutputStream(delete);
+ out.close();
+ } catch (IOException e) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("Unable to write " + delete.getPath() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ } else {
+ compact(target); /* descend into directory */
+ }
+ }
+ }
+
+ public long getFreeSpace() throws IOException {
+ // cannot implement this without native code!
+ return -1;
+ }
+
+ public File getDataFile(BaseData data, String path) {
+ BaseStorageHook storageHook = (BaseStorageHook) data.getStorageHook(BaseStorageHook.KEY);
+ if (storageHook == null)
+ return null;
+ return storageHook.getDataFile(path);
+ }
+
+ public void installNativeCode(BaseData data, String[] nativepaths) throws BundleException {
+ for (int i = 0; i < nativepaths.length; i++) {
+ // extract the native code
+ File nativeFile = data.getBundleFile().getFile(nativepaths[i], true);
+ if (nativeFile == null)
+ throw new BundleException(NLS.bind(AdaptorMsg.BUNDLE_NATIVECODE_EXCEPTION, nativepaths[i]));
+ }
+ if (nativepaths.length > 0) {
+ BaseStorageHook storageHook = (BaseStorageHook) data.getStorageHook(BaseStorageHook.KEY);
+ if (storageHook != null)
+ storageHook.setNativePaths(nativepaths);
+ }
+ }
+
+ public Dictionary loadManifest(BaseData data) throws BundleException {
+ return loadManifest(data, false);
+ }
+
+ public Dictionary loadManifest(BaseData bundleData, boolean firstTime) throws BundleException {
+ Dictionary result = null;
+ StorageHook[] dataStorageHooks = bundleData.getStorageHooks();
+ for (int i = 0; i < dataStorageHooks.length && result == null; i++)
+ result = dataStorageHooks[i].getManifest(firstTime);
+ if (result == null)
+ result = AdaptorUtil.loadManifestFrom(bundleData);
+ if (result == null)
+ throw new BundleException(NLS.bind(AdaptorMsg.MANIFEST_NOT_FOUND_EXCEPTION, Constants.OSGI_BUNDLE_MANIFEST, bundleData.getLocation()));
+ return result;
+ }
+
+ public File getExtractFile(BaseData data, String path) {
+ BaseStorageHook storageHook = (BaseStorageHook) data.getStorageHook(BaseStorageHook.KEY);
+ if (storageHook == null)
+ return null;
+ // first check the child generation dir
+ File childGenDir = storageHook.getGenerationDir();
+ if (childGenDir != null) {
+ File childPath = new File(childGenDir, path);
+ if (childPath.exists())
+ return childPath;
+ }
+ // now check the parent
+ File parentGenDir = storageHook.getParentGenerationDir();
+ if (parentGenDir != null) {
+ // there is a parent generation check if the file exists
+ File parentPath = new File(parentGenDir, path);
+ if (parentPath.exists())
+ // only use the parent generation file if it exists; do not extract there
+ return parentPath;
+ }
+ // did not exist in both locations; create a file for extraction.
+ File bundleGenerationDir = storageHook.createGenerationDir();
+ /* if the generation dir exists, then we have place to cache */
+ if (bundleGenerationDir != null && bundleGenerationDir.exists())
+ return new File(bundleGenerationDir, path);
+ return null;
+ }
+
+ public BaseData[] getInstalledBundles() {
+ return readBundleDatas();
+ }
+
+ private BaseData[] readBundleDatas() {
+ InputStream bundleDataStream = findStorageStream(LocationManager.BUNDLE_DATA_FILE);
+ if (bundleDataStream == null)
+ return null;
+ try {
+ DataInputStream in = new DataInputStream(new BufferedInputStream(bundleDataStream));
+ try {
+ byte version = in.readByte();
+ if (version != BUNDLEDATA_VERSION)
+ return null;
+ timeStamp = in.readLong();
+ initialBundleStartLevel = in.readInt();
+ nextId = in.readLong();
+
+ int numStorageHooks = in.readInt();
+ StorageHook[] storageHooks = adaptor.getHookRegistry().getStorageHooks();
+ if (numStorageHooks != storageHooks.length)
+ return null; // must have the same number of storagehooks to properly read the data
+ for (int i = 0; i < numStorageHooks; i++) {
+ Object storageKey = storageHooks[i].getKey();
+ int storageVersion = storageHooks[i].getStorageVersion();
+ if (!storageKey.equals(in.readUTF()) || storageVersion != in.readInt())
+ return null; // some storage hooks have changed must throw the data away.
+ }
+
+ int bundleCount = in.readInt();
+ ArrayList result = new ArrayList(bundleCount);
+ long id = -1;
+ boolean bundleDiscarded = false;
+ for (int i = 0; i < bundleCount; i++) {
+ boolean error = false;
+ BaseData data = null;
+ try {
+ id = in.readLong();
+ if (id != 0) {
+ data = loadBaseData(id, in);
+ data.getBundleFile();
+ StorageHook[] dataStorageHooks = data.getStorageHooks();
+ for (int j = 0; j < dataStorageHooks.length; j++)
+ dataStorageHooks[j].validate();
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("BundleData created: " + data); //$NON-NLS-1$
+ processExtension(data, EXTENSION_INITIALIZE);
+ result.add(data);
+ }
+ } catch (IllegalArgumentException e) {
+ // may be from data.getBundleFile()
+ bundleDiscarded = true;
+ error = true;
+ } catch (BundleException e) {
+ // should never happen
+ bundleDiscarded = true;
+ error = true;
+ } catch (IOException e) {
+ bundleDiscarded = true;
+ error = true;
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
+ Debug.println("Error reading framework metadata: " + e.getMessage()); //$NON-NLS-1$
+ Debug.printStackTrace(e);
+ }
+ }
+ if (error && data != null) {
+ BaseStorageHook storageHook = (BaseStorageHook) data.getStorageHook(BaseStorageHook.KEY);
+ storageHook.delete(true, BaseStorageHook.DEL_BUNDLE_STORE);
+ }
+ }
+ if (bundleDiscarded)
+ FrameworkProperties.setProperty(EclipseStarter.PROP_REFRESH_BUNDLES, "true"); //$NON-NLS-1$
+ return (BaseData[]) result.toArray(new BaseData[result.size()]);
+ } finally {
+ in.close();
+ }
+ } catch (IOException e) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
+ Debug.println("Error reading framework metadata: " + e.getMessage()); //$NON-NLS-1$
+ Debug.printStackTrace(e);
+ }
+ }
+ return null;
+ }
+
+ private void saveAllData(boolean shutdown) {
+ saveBundleDatas();
+ saveStateData(shutdown);
+ savePermissionStorage();
+ if (shutdown)
+ stateManager.stopDataManager();
+ }
+
+ private BasePermissionStorage readPermissionData() {
+ BasePermissionStorage result = new BasePermissionStorage(this);
+ InputStream permDataStream = findStorageStream(PERM_DATA_FILE);
+ if (permDataStream == null)
+ return result;
+ try {
+ DataInputStream in = new DataInputStream(new BufferedInputStream(permDataStream));
+ try {
+ if (PERMDATA_VERSION != in.readByte())
+ return result;
+ // read the default permissions first
+ int numPerms = in.readInt();
+ if (numPerms > 0) {
+ String[] perms = new String[numPerms];
+ for (int i = 0; i < numPerms; i++)
+ perms[i] = in.readUTF();
+ result.setPermissionData(null, perms);
+ }
+ int numLocs = in.readInt();
+ if (numLocs > 0)
+ for (int i = 0; i < numLocs; i++) {
+ String loc = in.readUTF();
+ numPerms = in.readInt();
+ String[] perms = new String[numPerms];
+ for (int j = 0; j < numPerms; j++)
+ perms[j] = in.readUTF();
+ result.setPermissionData(loc, perms);
+ }
+ int numCondPerms = in.readInt();
+ if (numCondPerms > 0) {
+ String[] condPerms = new String[numCondPerms];
+ for (int i = 0; i < numCondPerms; i++)
+ condPerms[i] = in.readUTF();
+ result.saveConditionalPermissionInfos(condPerms);
+ }
+ result.setDirty(false);
+ } finally {
+ in.close();
+ }
+ } catch (IOException e) {
+ adaptor.getFrameworkLog().log(new FrameworkEvent(FrameworkEvent.ERROR, context.getBundle(), e));
+ }
+ return result;
+ }
+
+ private void savePermissionStorage() {
+ if (permissionStorage == null || !permissionStorage.isDirty())
+ return;
+ try {
+ ManagedOutputStream fmos = storageManager.getOutputStream(PERM_DATA_FILE);
+ DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fmos));
+ boolean error = true;
+ try {
+ out.writeByte(PERMDATA_VERSION);
+ // always write the default permissions first
+ String[] defaultPerms = permissionStorage.getPermissionData(null);
+ out.writeInt(defaultPerms == null ? 0 : defaultPerms.length);
+ if (defaultPerms != null)
+ for (int i = 0; i < defaultPerms.length; i++)
+ out.writeUTF(defaultPerms[i]);
+ String[] locations = permissionStorage.getLocations();
+ out.writeInt(locations == null ? 0 : locations.length);
+ if (locations != null)
+ for (int i = 0; i < locations.length; i++) {
+ out.writeUTF(locations[i]);
+ String[] perms = permissionStorage.getPermissionData(locations[i]);
+ out.writeInt(perms == null ? 0 : perms.length);
+ if (perms != null)
+ for (int j = 0; j < perms.length; j++)
+ out.writeUTF(perms[j]);
+ }
+ String[] condPerms = permissionStorage.getConditionalPermissionInfos();
+ out.writeInt(condPerms == null ? 0 : condPerms.length);
+ if (condPerms != null)
+ for (int i = 0; i < condPerms.length; i++)
+ out.writeUTF(condPerms[i]);
+ out.close();
+ permissionStorage.setDirty(false);
+ error = false;
+ } finally {
+ // if something happens, don't close a corrupt file
+ if (error) {
+ fmos.abort();
+ try {
+ out.close();
+ } catch (IOException e) {/*ignore*/
+ }
+ }
+ }
+ } catch (IOException e) {
+ adaptor.getFrameworkLog().log(new FrameworkEvent(FrameworkEvent.ERROR, context.getBundle(), e));
+ return;
+ }
+ }
+
+ private void saveBundleDatas() {
+ // the cache and the state match
+ if (stateManager == null || isReadOnly() || timeStamp == stateManager.getSystemState().getTimeStamp())
+ return;
+ try {
+ ManagedOutputStream fmos = storageManager.getOutputStream(LocationManager.BUNDLE_DATA_FILE);
+ DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fmos));
+ boolean error = true;
+ try {
+ out.writeByte(BUNDLEDATA_VERSION);
+ out.writeLong(stateManager.getSystemState().getTimeStamp());
+ out.writeInt(initialBundleStartLevel);
+ out.writeLong(nextId);
+
+ StorageHook[] storageHooks = adaptor.getHookRegistry().getStorageHooks();
+ out.writeInt(storageHooks.length);
+ for (int i = 0; i < storageHooks.length; i++) {
+ out.writeUTF((String) storageHooks[i].getKey());
+ out.writeInt(storageHooks[i].getStorageVersion());
+ }
+
+ Bundle[] bundles = context.getBundles();
+ out.writeInt(bundles.length);
+ for (int i = 0; i < bundles.length; i++) {
+ long id = bundles[i].getBundleId();
+ out.writeLong(id);
+ if (id != 0) {
+ BundleData data = ((org.eclipse.osgi.framework.internal.core.AbstractBundle) bundles[i]).getBundleData();
+ saveBaseData((BaseData) data, out);
+ }
+ }
+ out.close();
+ // update the 'timeStamp' after the changed Meta data is saved.
+ timeStamp = stateManager.getSystemState().getTimeStamp();
+ error = false;
+ } finally {
+ // if something happens, don't close a corrupt file
+ if (error) {
+ fmos.abort();
+ try {
+ out.close();
+ } catch (IOException e) {/*ignore*/
+ }
+ }
+ }
+ } catch (IOException e) {
+ adaptor.getFrameworkLog().log(new FrameworkEvent(FrameworkEvent.ERROR, context.getBundle(), e));
+ return;
+ }
+ }
+
+ private void saveStateData(boolean shutdown) {
+ if (stateManager == null || isReadOnly() || !stateManager.saveNeeded())
+ return;
+ try {
+ File stateTmpFile = File.createTempFile(LocationManager.STATE_FILE, ".new", LocationManager.getOSGiConfigurationDir()); //$NON-NLS-1$
+ File lazyTmpFile = File.createTempFile(LocationManager.LAZY_FILE, ".new", LocationManager.getOSGiConfigurationDir()); //$NON-NLS-1$
+ if (shutdown)
+ stateManager.shutdown(stateTmpFile, lazyTmpFile);
+ else
+ synchronized (stateManager) {
+ stateManager.update(stateTmpFile, lazyTmpFile);
+ }
+ storageManager.lookup(LocationManager.STATE_FILE, true);
+ storageManager.lookup(LocationManager.LAZY_FILE, true);
+ storageManager.update(new String[] {LocationManager.STATE_FILE, LocationManager.LAZY_FILE}, new String[] {stateTmpFile.getName(), lazyTmpFile.getName()});
+ } catch (IOException e) {
+ adaptor.getFrameworkLog().log(new FrameworkEvent(FrameworkEvent.ERROR, context.getBundle(), e));
+ }
+ }
+
+ public PermissionStorage getPermissionStorage() throws IOException {
+ if (permissionStorage == null)
+ permissionStorage = readPermissionData();
+ return permissionStorage;
+ }
+
+ public int getInitialBundleStartLevel() {
+ return initialBundleStartLevel;
+ }
+
+ public void setInitialBundleStartLevel(int value) {
+ this.initialBundleStartLevel = value;
+ requestSave();
+ }
+
+ public void save(BaseData data) throws IOException {
+ if (data.isDirty()) {
+ timeStamp--; // Change the value of the timeStamp, as a marker that something changed.
+ requestSave();
+ data.setDirty(false);
+ }
+ }
+
+ public BundleOperation installBundle(String location, URLConnection source) {
+ BaseData data = createBaseData(getNextBundleId(), location);
+ return new BundleInstall(data, source, this);
+ }
+
+ public BundleOperation updateBundle(BaseData data, URLConnection source) {
+ return new BundleUpdate(data, source, this);
+ }
+
+ public BundleOperation uninstallBundle(BaseData data) {
+ return new BundleUninstall(data, this);
+ }
+
+ protected Object getBundleContent(BaseData bundledata) throws IOException {
+ BaseStorageHook storageHook = (BaseStorageHook) bundledata.getStorageHook(BaseStorageHook.KEY);
+ if (storageHook == null)
+ throw new IllegalStateException();
+ return storageHook.isReference() ? new File(storageHook.getFileName()) : new File(storageHook.getGenerationDir(), storageHook.getFileName());
+ }
+
+ public BundleFile createBundleFile(Object content, BaseData data) throws IOException {
+ boolean base = false;
+ if (content == null) {
+ // this must be a request for the base bundlefile
+ base = true;
+ // get the content of this bundle
+ content = getBundleContent(data);
+ }
+ // Ask factories before doing the default behavior
+ BundleFileFactoryHook[] factories = adaptor.getHookRegistry().getBundleFileFactoryHooks();
+ for (int i = 0; i < factories.length; i++) {
+ BundleFile result = factories[i].createBundleFile(content, data, base);
+ if (result != null)
+ return result;
+ }
+ // No factories configured or they declined to create the bundle file; do default
+ if (content instanceof File) {
+ File file = (File) content;
+ if (file.isDirectory())
+ return new DirBundleFile(file);
+ return new ZipBundleFile(file, data);
+ }
+ // nothing we can do; must throw exception for the content
+ throw new IOException("Cannot create bundle file for content of type: " + content.getClass().getName());
+ }
+
+ public synchronized StateManager getStateManager() {
+ if (stateManager != null)
+ return stateManager;
+ stateManager = readStateData();
+ checkSystemState(stateManager.getSystemState());
+ return stateManager;
+ }
+
+ private void checkSystemState(State state) {
+ BundleDescription[] bundles = state.getBundles();
+ if (bundles == null)
+ return;
+ boolean removedBundle = false;
+ for (int i = 0; i < bundles.length; i++) {
+ if (context.getBundle(bundles[i].getBundleId()) == null) {
+ state.removeBundle(bundles[i]);
+ removedBundle = true;
+ }
+ }
+ if (removedBundle)
+ state.resolve(false); // do a full resolve
+ BundleDescription systemBundle = state.getBundle(0);
+ if (systemBundle == null || !systemBundle.isResolved())
+ // this would be a bug in the framework
+ throw new IllegalStateException();
+ }
+
+ private StateManager readStateData() {
+ File[] stateFiles = findStorageFiles(new String[] {LocationManager.STATE_FILE, LocationManager.LAZY_FILE});
+ File stateFile = stateFiles[0];
+ File lazyFile = stateFiles[1];
+
+ stateManager = new StateManager(stateFile, lazyFile, context, timeStamp);
+ State systemState = null;
+ if (!invalidState) {
+ systemState = stateManager.readSystemState();
+ if (systemState != null)
+ return stateManager;
+ }
+ systemState = stateManager.createSystemState();
+ Bundle[] installedBundles = context.getBundles();
+ if (installedBundles == null)
+ return stateManager;
+ StateObjectFactory factory = stateManager.getFactory();
+ for (int i = 0; i < installedBundles.length; i++) {
+ AbstractBundle toAdd = (AbstractBundle) installedBundles[i];
+ try {
+ // make sure we get the real manifest as if this is the first time.
+ Dictionary toAddManifest = loadManifest((BaseData) toAdd.getBundleData(), true);
+ BundleDescription newDescription = factory.createBundleDescription(systemState, toAddManifest, toAdd.getLocation(), toAdd.getBundleId());
+ systemState.addBundle(newDescription);
+ } catch (BundleException be) {
+ // just ignore bundle datas with invalid manifests
+ }
+ }
+ // we need the state resolved
+ systemState.setTimeStamp(timeStamp);
+ systemState.resolve();
+ invalidState = false;
+ return stateManager;
+ }
+
+ private File[] findStorageFiles(String[] fileNames) {
+ File[] storageFiles = new File[fileNames.length];
+ try {
+ for (int i = 0; i < storageFiles.length; i++)
+ storageFiles[i] = storageManager.lookup(fileNames[i], false);
+ } catch (IOException ex) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
+ Debug.println("Error reading state file " + ex.getMessage()); //$NON-NLS-1$
+ Debug.printStackTrace(ex);
+ }
+ }
+ boolean success = true;
+ for (int i = 0; i < storageFiles.length; i++)
+ if (storageFiles[i] == null || !storageFiles[i].isFile()) {
+ success = false;
+ break;
+ }
+ if (success)
+ return storageFiles;
+ //if it does not exist, try to read it from the parent
+ Location parentConfiguration = null;
+ Location currentConfiguration = LocationManager.getConfigurationLocation();
+ if (currentConfiguration != null && (parentConfiguration = currentConfiguration.getParentLocation()) != null) {
+ try {
+ File stateLocationDir = new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME);
+ StorageManager newFileManager = initFileManager(stateLocationDir, "none", true); //$NON-NLS-1$);
+ for (int i = 0; i < storageFiles.length; i++)
+ storageFiles[i] = newFileManager.lookup(fileNames[i], false);
+ newFileManager.close();
+ } catch (IOException ex) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
+ Debug.println("Error reading state file " + ex.getMessage()); //$NON-NLS-1$
+ Debug.printStackTrace(ex);
+ }
+ }
+ } else {
+ try {
+ //it did not exist in either place, so create it in the original location
+ if (!isReadOnly()) {
+ for (int i = 0; i < storageFiles.length; i++)
+ storageFiles[i] = storageManager.lookup(fileNames[i], true);
+ }
+ } catch (IOException ex) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
+ Debug.println("Error reading state file " + ex.getMessage()); //$NON-NLS-1$
+ Debug.printStackTrace(ex);
+ }
+ }
+ }
+ return storageFiles;
+ }
+
+ public void frameworkStart(BundleContext fwContext) throws BundleException {
+ this.context = fwContext;
+ // System property can be set to enable state saver or not.
+ if (Boolean.valueOf(FrameworkProperties.getProperty(BaseStorage.PROP_ENABLE_STATE_SAVER, "true")).booleanValue()) //$NON-NLS-1$
+ stateSaver = new StateSaver();
+
+ }
+
+ public void frameworkStop(BundleContext fwContext) throws BundleException {
+ if (stateSaver != null)
+ stateSaver.shutdown();
+ saveAllData(true);
+ storageManager.close();
+ }
+
+ public void frameworkStopping(BundleContext fwContext) {
+ // do nothing in storage
+ }
+
+ public void addProperties(Properties properties) {
+ // set the extension support if we found the addURL method
+ if (addURLMethod != null)
+ properties.put(Constants.SUPPORTS_FRAMEWORK_EXTENSION, "true"); //$NON-NLS-1$
+ // store bundleStore back into adaptor properties for others to see
+ properties.put(BaseStorage.PROP_BUNDLE_STORE, getBundleStoreRoot().getAbsolutePath());
+ }
+
+ private InputStream findStorageStream(String fileName) {
+ InputStream storageStream = null;
+ try {
+ storageStream = storageManager.getInputStream(fileName);
+ } catch (IOException ex) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
+ Debug.println("Error reading framework metadata: " + ex.getMessage()); //$NON-NLS-1$
+ Debug.printStackTrace(ex);
+ }
+ }
+ if (storageStream == null) {
+ Location currentConfiguration = LocationManager.getConfigurationLocation();
+ Location parentConfiguration = null;
+ if (currentConfiguration != null && (parentConfiguration = currentConfiguration.getParentLocation()) != null) {
+ try {
+ File bundledataLocationDir = new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME);
+ StorageManager newStorageManager = initFileManager(bundledataLocationDir, "none", true); //$NON-NLS-1$
+ storageStream = newStorageManager.getInputStream(fileName);
+ newStorageManager.close();
+ } catch (MalformedURLException e1) {
+ // This will not happen since all the URLs are derived by us
+ // and we are GODS!
+ } catch (IOException e1) {
+ // That's ok we will regenerate the .bundleData
+ }
+ }
+ }
+ return storageStream;
+ }
+
+ protected void saveBaseData(BaseData bundledata, DataOutputStream out) throws IOException {
+ StorageHook[] hooks = bundledata.getStorageHooks();
+ out.writeInt(hooks.length);
+ for (int i = 0; i < hooks.length; i++) {
+ out.writeUTF((String) hooks[i].getKey());
+ hooks[i].save(out);
+ }
+ }
+
+ protected BaseData loadBaseData(long id, DataInputStream in) throws IOException {
+ BaseData result = new BaseData(id, adaptor);
+ int numHooks = in.readInt();
+ StorageHook[] hooks = new StorageHook[numHooks];
+ for (int i = 0; i < numHooks; i++) {
+ String hookKey = in.readUTF();
+ StorageHook storageHook = (StorageHook) storageHooks.getByKey(hookKey);
+ if (storageHook == null)
+ throw new IOException();
+ hooks[i] = storageHook.load(result, in);
+ }
+ result.setStorageHooks(hooks);
+ return result;
+ }
+
+ protected BaseData createBaseData(long id, String location) {
+ BaseData result = new BaseData(id, adaptor);
+ result.setLocation(location);
+ return result;
+ }
+
+ public String getInstallPath() {
+ return installPath;
+ }
+
+ private void cleanOSGiCache() {
+ File osgiConfig = LocationManager.getOSGiConfigurationDir();
+ if (!AdaptorUtil.rm(osgiConfig)) {
+ // TODO log error?
+ }
+ }
+
+ /**
+ * Processes an extension bundle
+ * @param bundleData the extension bundle data
+ * @param type the type of extension bundle
+ * @throws BundleException on any errors or if the extension bundle type is not supported
+ */
+ protected void processExtension(BaseData bundleData, byte type) throws BundleException {
+ if ((bundleData.getType() & BundleData.TYPE_FRAMEWORK_EXTENSION) != 0) {
+ validateExtension(bundleData);
+ processFrameworkExtension(bundleData, type);
+ } else if ((bundleData.getType() & BundleData.TYPE_BOOTCLASSPATH_EXTENSION) != 0) {
+ validateExtension(bundleData);
+ processBootExtension(bundleData, type);
+ }
+ }
+
+ /**
+ * Validates the extension bundle metadata
+ * @param bundleData the extension bundle data
+ * @throws BundleException if the extension bundle metadata is invalid
+ */
+ private void validateExtension(BundleData bundleData) throws BundleException {
+ Dictionary extensionManifest = bundleData.getManifest();
+ if (extensionManifest.get(Constants.IMPORT_PACKAGE) != null)
+ throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_EXTENSION_IMPORT_ERROR, bundleData.getLocation()));
+ if (extensionManifest.get(Constants.REQUIRE_BUNDLE) != null)
+ throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_EXTENSION_REQUIRE_ERROR, bundleData.getLocation()));
+ if (extensionManifest.get(Constants.BUNDLE_NATIVECODE) != null)
+ throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_EXTENSION_NATIVECODE_ERROR, bundleData.getLocation()));
+ }
+
+ /**
+ * Processes a framework extension bundle
+ * @param bundleData the extension bundle data
+ * @param type the type of extension bundle
+ * @throws BundleException on errors or if framework extensions are not supported
+ */
+ protected void processFrameworkExtension(BaseData bundleData, byte type) throws BundleException {
+ if (addURLMethod == null)
+ throw new BundleException("Framework extensions are not supported.", new UnsupportedOperationException()); //$NON-NLS-1$
+ if ((type & (EXTENSION_UNINSTALLED | EXTENSION_UPDATED)) != 0)
+ // if uninstalled or updated then do nothing framework must be restarted.
+ return;
+
+ // first make sure this BundleData is not on the pre-configured osgi.framework.extensions list
+ String[] extensions = getConfiguredExtensions();
+ for (int i = 0; i < extensions.length; i++)
+ if (extensions[i].equals(bundleData.getSymbolicName()))
+ return;
+ File[] files = getExtensionFiles(bundleData);
+ if (files == null)
+ return;
+ ClassLoader cl = getClass().getClassLoader();
+ for (int i = 0; i < files.length; i++) {
+ if (files[i] == null)
+ continue;
+ Throwable exceptionLog = null;
+ try {
+ addURLMethod.invoke(cl, new Object[] {files[i].toURL()});
+ } catch (InvocationTargetException e) {
+ exceptionLog = e.getTargetException();
+ } catch (Throwable t) {
+ exceptionLog = t;
+ } finally {
+ if (exceptionLog != null)
+ adaptor.getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundleData.getBundle(), exceptionLog);
+ }
+ }
+ try {
+ cl.loadClass("thisIsNotAClass"); // initialize the new urls //$NON-NLS-1$
+ } catch (ClassNotFoundException e) {
+ // do nothing
+ }
+ }
+
+ /**
+ * Returns a list of configured extensions
+ * @return a list of configured extensions
+ */
+ protected String[] getConfiguredExtensions() {
+ if (configuredExtensions != null)
+ return configuredExtensions;
+ String prop = FrameworkProperties.getProperty(BaseStorage.PROP_FRAMEWORK_EXTENSIONS);
+ if (prop == null || prop.trim().length() == 0)
+ configuredExtensions = new String[0];
+ else
+ configuredExtensions = ManifestElement.getArrayFromList(prop);
+ return configuredExtensions;
+ }
+
+ /**
+ * Processes a boot extension bundle
+ * @param bundleData the extension bundle data
+ * @param type the type of extension bundle
+ * @throws BundleException on errors or if boot extensions are not supported
+ */
+ protected void processBootExtension(BundleData bundleData, byte type) throws BundleException {
+ throw new BundleException("Boot classpath extensions are not supported.", new UnsupportedOperationException()); //$NON-NLS-1$
+ }
+
+ private void initBundleStoreRoot() {
+ File configurationLocation = LocationManager.getOSGiConfigurationDir();
+ if (configurationLocation != null)
+ bundleStoreRoot = new File(configurationLocation, LocationManager.BUNDLES_DIR);
+ else
+ // last resort just default to "bundles"
+ bundleStoreRoot = new File(LocationManager.BUNDLES_DIR);
+ }
+
+ public File getBundleStoreRoot() {
+ if (bundleStoreRoot == null)
+ initBundleStoreRoot();
+ return bundleStoreRoot;
+ }
+
+ /**
+ * Returns a list of classpath files for an extension bundle
+ * @param bundleData the bundle data for an extension bundle
+ * @return a list of classpath files for an extension bundle
+ */
+ protected File[] getExtensionFiles(BaseData bundleData) {
+ File[] files = null;
+ try {
+ String[] paths = bundleData.getClassPath();
+ // TODO need to be smarter about dev path here
+ if (FrameworkProperties.getProperty("osgi.dev") != null) { //$NON-NLS-1$
+ String[] origPaths = paths;
+ paths = new String[origPaths.length + 1];
+ System.arraycopy(origPaths, 0, paths, 0, origPaths.length);
+ paths[paths.length - 1] = "bin"; //$NON-NLS-1$
+ }
+ ArrayList results = new ArrayList(paths.length);
+ for (int i = 0; i < paths.length; i++) {
+ if (".".equals(paths[i])) //$NON-NLS-1$
+ results.add(bundleData.getBundleFile().getBaseFile());
+ else {
+ File result = bundleData.getBundleFile().getFile(paths[i], false);
+ if (result != null)
+ results.add(result);
+ }
+ }
+ return (File[]) results.toArray(new File[results.size()]);
+ } catch (BundleException e) {
+ adaptor.getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundleData.getBundle(), e);
+ }
+ return files;
+ }
+
+ void requestSave() {
+ // Only when the State saver is enabled will the stateSaver be started.
+ if (stateSaver == null)
+ return;
+ stateSaver.requestSave();
+ }
+
+ /**
+ * Updates the state mananager with an updated/installed/uninstalled bundle
+ * @param bundleData the modified bundle
+ * @param type the type of modification
+ * @throws BundleException
+ */
+ public void updateState(BundleData bundleData, int type) throws BundleException {
+ if (stateManager == null) {
+ invalidState = true;
+ return;
+ }
+ State systemState = stateManager.getSystemState();
+ switch (type) {
+ case BundleEvent.UPDATED :
+ systemState.removeBundle(bundleData.getBundleID());
+ // fall through to INSTALLED
+ case BundleEvent.INSTALLED :
+ BundleDescription newDescription = stateManager.getFactory().createBundleDescription(systemState, bundleData.getManifest(), bundleData.getLocation(), bundleData.getBundleID());
+ systemState.addBundle(newDescription);
+ break;
+ case BundleEvent.UNINSTALLED :
+ systemState.removeBundle(bundleData.getBundleID());
+ break;
+ }
+ }
+
+ private static Method findaddURLMethod(Class clazz) {
+ if (clazz == null)
+ return null; // ends the recursion when getSuperClass returns null
+ try {
+ Method result = clazz.getDeclaredMethod("addURL", new Class[] {URL.class}); //$NON-NLS-1$
+ result.setAccessible(true);
+ return result;
+ } catch (NoSuchMethodException e) {
+ // do nothing look in super class below
+ } catch (SecurityException e) {
+ // if we do not have the permissions then we will not find the method
+ }
+ return findaddURLMethod(clazz.getSuperclass());
+ }
+
+ private class StateSaver implements Runnable {
+ private long delay_interval = 30000; // 30 seconds.
+ private long max_total_delay_interval = 1800000; // 30 minutes.
+ private boolean shutdown = false;
+ private long lastSaveTime = 0;
+ private Thread runningThread = null;
+
+ StateSaver() {
+ String prop = FrameworkProperties.getProperty("eclipse.stateSaveDelayInterval"); //$NON-NLS-1$
+ if (prop != null) {
+ try {
+ long val = Long.parseLong(prop);
+ if (val >= 1000 && val <= 1800000) {
+ delay_interval = val;
+ max_total_delay_interval = val * 60;
+ }
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ }
+
+ public void run() {
+ State systemState = adaptor.getState();
+ synchronized (systemState) {
+ long firstSaveTime = lastSaveTime;
+ long curSaveTime = 0;
+ long delayTime;
+ do {
+ do {
+ if ((System.currentTimeMillis() - firstSaveTime) > max_total_delay_interval)
+ // Waiting time has been too long, so break to start saving State data to file.
+ break;
+ delayTime = Math.min(delay_interval, lastSaveTime - curSaveTime);
+ curSaveTime = lastSaveTime;
+ // wait for other save requests
+ try {
+ if (!shutdown)
+ systemState.wait(delayTime);
+ } catch (InterruptedException ie) {
+ // force break from do/while loops
+ curSaveTime = lastSaveTime;
+ break;
+ }
+
+ // Continue the loop if 'lastSaveTime' is increased again during waiting.
+ } while (!shutdown && curSaveTime < lastSaveTime);
+ // Save State and Meta data.
+ saveAllData(false);
+ // Continue the loop if Saver is asked again during saving State data to file.
+ } while (!shutdown && curSaveTime < lastSaveTime);
+ runningThread = null; // clear runningThread
+ }
+ }
+
+ void shutdown() {
+ State systemState = adaptor.getState();
+ Thread joinWith = null;
+ synchronized (systemState) {
+ shutdown = true;
+ joinWith = runningThread;
+ systemState.notifyAll(); // To wakeup sleeping thread.
+ }
+ try {
+ if (joinWith != null)
+ // There should be no deadlock when 'shutdown' is true.
+ joinWith.join();
+ } catch (InterruptedException ie) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
+ Debug.println("Error shutdowning StateSaver: " + ie.getMessage()); //$NON-NLS-1$
+ Debug.printStackTrace(ie);
+ }
+ }
+ }
+
+ void requestSave() {
+ State systemState = adaptor.getState();
+ synchronized (systemState) {
+ lastSaveTime = System.currentTimeMillis();
+ if (runningThread == null) {
+ runningThread = new Thread(this, "State Saver"); //$NON-NLS-1$
+ runningThread.start();
+ }
+ }
+ }
+ }
+
+ public long getNextBundleId() {
+ return nextId++;
+ }
+
+ public static BaseStorage getInstance() {
+ return INSTANCE;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorageHook.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorageHook.java
new file mode 100644
index 000000000..2504befd2
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorageHook.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.baseadaptor;
+
+import java.io.*;
+import java.util.Dictionary;
+import org.eclipse.core.runtime.adaptor.LocationManager;
+import org.eclipse.osgi.baseadaptor.*;
+import org.eclipse.osgi.baseadaptor.hooks.StorageHook;
+import org.eclipse.osgi.framework.adaptor.*;
+import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.framework.internal.core.*;
+import org.eclipse.osgi.framework.util.KeyedElement;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.eclipse.osgi.util.ManifestElement;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Version;
+
+public class BaseStorageHook implements StorageHook {
+ public static final String KEY = BaseStorageHook.class.getName();
+ public static final int HASHCODE = KEY.hashCode();
+ public static final int DEL_BUNDLE_STORE = 0x01;
+ public static final int DEL_GENERATION = 0x02;
+ private static final int STORAGE_VERSION = 1;
+
+ /** bundle's file name */
+ private String fileName;
+ /** native code paths for this BundleData */
+ private String[] nativePaths;
+ /** bundle generation */
+ private int generation = 1;
+ /** Is bundle a reference */
+ private boolean reference;
+
+ private BaseData bundleData;
+ private BaseStorage storage;
+ private File bundleStore;
+ private File dataStore;
+
+ public BaseStorageHook(BaseStorage storage) {
+ this.storage = storage;
+ }
+
+ public int getStorageVersion() {
+ return STORAGE_VERSION;
+ }
+
+ public StorageHook create(BaseData bundledata) throws BundleException {
+ BaseStorageHook storageHook = new BaseStorageHook(storage);
+ storageHook.bundleData = bundledata;
+ return storageHook;
+ }
+
+ public void initialize(Dictionary manifest) throws BundleException {
+ BaseStorageHook.loadManifest(bundleData, manifest);
+ }
+
+ static void loadManifest(BaseData target, Dictionary manifest) throws BundleException {
+ try {
+ target.setVersion(Version.parseVersion((String) manifest.get(Constants.BUNDLE_VERSION)));
+ } catch (IllegalArgumentException e) {
+ target.setVersion(new InvalidVersion((String) manifest.get(Constants.BUNDLE_VERSION)));
+ }
+ ManifestElement[] bsnHeader = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME));
+ int bundleType = 0;
+ if (bsnHeader != null) {
+ target.setSymbolicName(bsnHeader[0].getValue());
+ String singleton = bsnHeader[0].getDirective(Constants.SINGLETON_DIRECTIVE);
+ if (singleton == null)
+ singleton = bsnHeader[0].getAttribute(Constants.SINGLETON_DIRECTIVE);
+ if ("true".equals(singleton)) //$NON-NLS-1$
+ bundleType |= BundleData.TYPE_SINGLETON;
+ }
+ target.setClassPathString((String) manifest.get(Constants.BUNDLE_CLASSPATH));
+ target.setActivator((String) manifest.get(Constants.BUNDLE_ACTIVATOR));
+ String host = (String) manifest.get(Constants.FRAGMENT_HOST);
+ if (host != null) {
+ bundleType |= BundleData.TYPE_FRAGMENT;
+ ManifestElement[] hostElement = ManifestElement.parseHeader(Constants.FRAGMENT_HOST, host);
+ if (Constants.getInternalSymbolicName().equals(hostElement[0].getValue()) || Constants.OSGI_SYSTEM_BUNDLE.equals(hostElement[0].getValue())) {
+ String extensionType = hostElement[0].getDirective("extension"); //$NON-NLS-1$
+ if (extensionType == null || extensionType.equals("framework")) //$NON-NLS-1$
+ bundleType |= BundleData.TYPE_FRAMEWORK_EXTENSION;
+ else
+ bundleType |= BundleData.TYPE_BOOTCLASSPATH_EXTENSION;
+ }
+ }
+ target.setType(bundleType);
+ target.setExecutionEnvironment((String) manifest.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT));
+ target.setDynamicImports((String) manifest.get(Constants.DYNAMICIMPORT_PACKAGE));
+ }
+
+ public StorageHook load(BaseData target, DataInputStream in) throws IOException {
+ target.setLocation(AdaptorUtil.readString(in, false));
+ target.setSymbolicName(AdaptorUtil.readString(in, false));
+ target.setVersion(AdaptorUtil.loadVersion(in));
+ target.setActivator(AdaptorUtil.readString(in, false));
+ target.setClassPathString(AdaptorUtil.readString(in, false));
+ target.setExecutionEnvironment(AdaptorUtil.readString(in, false));
+ target.setDynamicImports(AdaptorUtil.readString(in, false));
+ target.setStartLevel(in.readInt());
+ target.setStatus(in.readInt());
+ target.setType(in.readInt());
+ target.setLastModified(in.readLong());
+ target.setDirty(false); // make sure to reset the dirty bit;
+
+ BaseStorageHook storageHook = new BaseStorageHook(storage);
+ storageHook.bundleData = target;
+ storageHook.generation = in.readInt();
+ storageHook.reference = in.readBoolean();
+ storageHook.fileName = getAbsolute(storageHook.reference, AdaptorUtil.readString(in, false));
+ int nativePathCount = in.readInt();
+ storageHook.nativePaths = nativePathCount > 0 ? new String[nativePathCount] : null;
+ for (int i = 0; i < nativePathCount; i++)
+ storageHook.nativePaths[i] = in.readUTF();
+ return storageHook;
+ }
+
+ private String getAbsolute(boolean isReference, String path) {
+ if (!isReference)
+ return path;
+ // fileName for bundles installed with reference URLs is stored relative to the install location
+ File storedPath = new File(path);
+ if (!storedPath.isAbsolute())
+ // make sure it has the absolute location instead
+ return new FilePath(storage.getInstallPath() + path).toString();
+ return path;
+ }
+
+ public void save(DataOutputStream out) throws IOException {
+ if (bundleData == null)
+ throw new IllegalStateException();
+ AdaptorUtil.writeStringOrNull(out, bundleData.getLocation());
+ AdaptorUtil.writeStringOrNull(out, bundleData.getSymbolicName());
+ AdaptorUtil.writeStringOrNull(out, bundleData.getVersion().toString());
+ AdaptorUtil.writeStringOrNull(out, bundleData.getActivator());
+ AdaptorUtil.writeStringOrNull(out, bundleData.getClassPathString());
+ AdaptorUtil.writeStringOrNull(out, bundleData.getExecutionEnvironment());
+ AdaptorUtil.writeStringOrNull(out, bundleData.getDynamicImports());
+ StorageHook[] hooks = bundleData.getStorageHooks();
+ boolean forgetStartLevel = false;
+ for (int i = 0; i < hooks.length && !forgetStartLevel; i++)
+ forgetStartLevel = hooks[i].forgetStartLevelChange(bundleData.getStartLevel());
+ out.writeInt(!forgetStartLevel ? bundleData.getStartLevel() : 1);
+ boolean forgetStatus = false;
+ // see if we should forget the persistently started flag
+ for (int i = 0; i < hooks.length && !forgetStatus; i++)
+ forgetStatus = hooks[i].forgetStatusChange(bundleData.getStatus());
+ out.writeInt(!forgetStatus ? bundleData.getStatus() : (~Constants.BUNDLE_STARTED) & bundleData.getStatus());
+ out.writeInt(bundleData.getType());
+ out.writeLong(bundleData.getLastModified());
+
+ out.writeInt(getGeneration());
+ out.writeBoolean(isReference());
+ String storedFileName = isReference() ? new FilePath(storage.getInstallPath()).makeRelative(new FilePath(getFileName())) : getFileName();
+ AdaptorUtil.writeStringOrNull(out, storedFileName);
+ if (nativePaths == null)
+ out.writeInt(0);
+ else {
+ out.writeInt(nativePaths.length);
+ for (int i = 0; i < nativePaths.length; i++)
+ out.writeUTF(nativePaths[i]);
+ }
+
+ }
+
+ public int getKeyHashCode() {
+ return HASHCODE;
+ }
+
+ public boolean compare(KeyedElement other) {
+ return other.getKey() == KEY;
+ }
+
+ public Object getKey() {
+ return KEY;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public int getGeneration() {
+ return generation;
+ }
+
+ public String[] getNativePaths() {
+ return nativePaths;
+ }
+
+ public void setNativePaths(String[] nativePaths) {
+ this.nativePaths = nativePaths;
+ }
+
+ public boolean isReference() {
+ return reference;
+ }
+
+ public File getBundleStore() {
+ if (bundleStore == null)
+ bundleStore = new File(storage.getBundleStoreRoot(), String.valueOf(bundleData.getBundleID()));
+ return bundleStore;
+ }
+
+ public File getDataFile(String path) {
+ // lazily initialize dirData to prevent early access to configuration location
+ if (dataStore == null)
+ dataStore = new File(getBundleStore(), BaseStorage.DATA_DIR_NAME);
+ if (path != null && !dataStore.exists() && (storage.isReadOnly() || !dataStore.mkdirs()))
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("Unable to create bundle data directory: " + dataStore.getPath()); //$NON-NLS-1$
+ return path == null ? dataStore : new File(dataStore, path);
+ }
+
+ void delete(boolean postpone, int type) throws IOException {
+ File delete = null;
+ switch (type) {
+ case DEL_GENERATION :
+ delete = getGenerationDir();
+ break;
+ case DEL_BUNDLE_STORE :
+ delete = getBundleStore();
+ break;
+ }
+ if (delete != null && delete.exists() && (postpone || !AdaptorUtil.rm(delete))) {
+ /* create .delete */
+ FileOutputStream out = new FileOutputStream(new File(delete, ".delete")); //$NON-NLS-1$
+ out.close();
+ }
+ }
+
+ File getGenerationDir() {
+ return new File(getBundleStore(), String.valueOf(getGeneration()));
+ }
+
+ File getParentGenerationDir() {
+ Location parentConfiguration = null;
+ Location currentConfiguration = LocationManager.getConfigurationLocation();
+ if (currentConfiguration != null && (parentConfiguration = currentConfiguration.getParentLocation()) != null)
+ return new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + '/' + LocationManager.BUNDLES_DIR + '/' + bundleData.getBundleID() + '/' + getGeneration());
+ return null;
+ }
+
+ File createGenerationDir() {
+ File generationDir = getGenerationDir();
+ if (!generationDir.exists() && (storage.isReadOnly() || !generationDir.mkdirs()))
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("Unable to create bundle generation directory: " + generationDir.getPath()); //$NON-NLS-1$
+ return generationDir;
+ }
+
+ public void setReference(boolean reference) {
+ this.reference = reference;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public void copy(StorageHook storageHook) {
+ if (!(storageHook instanceof BaseStorageHook))
+ throw new IllegalArgumentException();
+ BaseStorageHook hook = (BaseStorageHook) storageHook;
+ bundleStore = hook.bundleStore;
+ dataStore = hook.dataStore;
+ generation = hook.generation + 1;
+ // fileName and reference will be set by update
+ }
+
+ public void validate() throws IllegalArgumentException {
+ // do nothing
+ }
+
+ public Dictionary getManifest(boolean firstLoad) throws BundleException {
+ // do nothing
+ return null;
+ }
+
+ public boolean forgetStatusChange(int status) {
+ // do nothing
+ return false;
+ }
+
+ public boolean forgetStartLevelChange(int startlevel) {
+ // do nothing
+ return false;
+ }
+
+ public boolean matchDNChain(String pattern) {
+ // do nothing
+ return false;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleInstall.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleInstall.java
new file mode 100644
index 000000000..6b52f01cf
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleInstall.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.baseadaptor;
+
+import java.io.*;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Dictionary;
+import org.eclipse.osgi.baseadaptor.*;
+import org.eclipse.osgi.baseadaptor.hooks.StorageHook;
+import org.eclipse.osgi.framework.adaptor.BundleData;
+import org.eclipse.osgi.framework.adaptor.BundleOperation;
+import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.framework.internal.core.ReferenceInputStream;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.*;
+
+public class BundleInstall implements BundleOperation {
+ private BaseData data;
+ private URLConnection source;
+ private BaseStorage storage;
+
+ public BundleInstall(BaseData data, URLConnection source, BaseStorage storage) {
+ this.data = data;
+ this.source = source;
+ this.storage = storage;
+ }
+
+ /**
+ * Begin the operation on the bundle (install, update, uninstall).
+ *
+ * @return BundleData object for the target bundle.
+ * @throws BundleException If a failure occured modifiying peristent storage.
+ */
+ public BundleData begin() throws BundleException {
+ try {
+ InputStream in = null;
+ try {
+ data.setLastModified(System.currentTimeMillis());
+ data.setStartLevel(storage.getInitialBundleStartLevel());
+ StorageHook[] storageHooks = data.getAdaptor().getHookRegistry().getStorageHooks();
+ StorageHook[] instanceHooks = new StorageHook[storageHooks.length];
+ for (int i = 0; i < storageHooks.length; i++)
+ instanceHooks[i] = storageHooks[i].create(data);
+ data.setStorageHooks(instanceHooks);
+ BaseStorageHook storageHook = (BaseStorageHook) data.getStorageHook(BaseStorageHook.KEY);
+ in = source.getInputStream();
+ URL sourceURL = source.getURL();
+ String protocol = sourceURL == null ? null : sourceURL.getProtocol();
+ if (in instanceof ReferenceInputStream) {
+ URL reference = ((ReferenceInputStream) in).getReference();
+ if (!"file".equals(reference.getProtocol())) //$NON-NLS-1$
+ throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_URL_CREATE_EXCEPTION, reference));
+ storageHook.setReference(true);
+ storageHook.setFileName(reference.getPath());
+ } else {
+ File genDir = storageHook.createGenerationDir();
+ if (!genDir.exists())
+ throw new IOException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, genDir.getPath()));
+ storageHook.setReference(false);
+ storageHook.setFileName(BaseStorage.BUNDLEFILE_NAME);
+ File outFile = new File(genDir, storageHook.getFileName());
+ if ("file".equals(protocol)) { //$NON-NLS-1$
+ File inFile = new File(source.getURL().getPath());
+ if (inFile.isDirectory())
+ AdaptorUtil.copyDir(inFile, outFile);
+ else
+ AdaptorUtil.readFile(in, outFile);
+ } else {
+ AdaptorUtil.readFile(in, outFile);
+ }
+ }
+ Dictionary manifest = storage.loadManifest(data, true);
+ for (int i = 0; i < instanceHooks.length; i++)
+ instanceHooks[i].initialize(manifest);
+ } finally {
+ try {
+ if (in != null)
+ in.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ } catch (IOException ioe) {
+ throw new BundleException(AdaptorMsg.BUNDLE_READ_EXCEPTION, ioe);
+ }
+
+ return (data);
+ }
+
+ public void undo() {
+ if (data != null) {
+ try {
+ data.close();
+ } catch (IOException e) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ Debug.println("Unable to close " + data + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ if (data != null) {
+ BaseStorageHook storageHook = (BaseStorageHook) data.getStorageHook(BaseStorageHook.KEY);
+ try {
+ if (storageHook != null)
+ storageHook.delete(false, BaseStorageHook.DEL_BUNDLE_STORE);
+ } catch (IOException e) {
+ data.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, data.getBundle(), e);
+ }
+ }
+ }
+
+ public void commit(boolean postpone) throws BundleException {
+ storage.processExtension(data, BaseStorage.EXTENSION_INSTALLED);
+ try {
+ data.save();
+ } catch (IOException e) {
+ throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e);
+ }
+ storage.updateState(data, BundleEvent.INSTALLED);
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUninstall.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUninstall.java
new file mode 100644
index 000000000..05d1fda15
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUninstall.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.baseadaptor;
+
+import java.io.*;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.framework.adaptor.BundleData;
+import org.eclipse.osgi.framework.adaptor.BundleOperation;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+
+public class BundleUninstall implements BundleOperation {
+ private BaseData data;
+ private BaseStorage storage;
+
+ public BundleUninstall(BaseData data, BaseStorage storage) {
+ this.data = data;
+ this.storage = storage;
+ }
+
+ /**
+ * Perform the change to persistent storage.
+ *
+ * @return Bundle object for the target bundle.
+ * @throws BundleException If a failure occured modifiying peristent storage.
+ */
+ public BundleData begin() throws BundleException {
+ return data;
+ }
+
+ /**
+ * Commit the change to persistent storage.
+ *
+ * @param postpone If true, the bundle's persistent
+ * storage cannot be immediately reclaimed.
+ * @throws BundleException If a failure occured modifiying peristent storage.
+ */
+ public void commit(boolean postpone) throws BundleException {
+ BaseStorageHook storageHook = (BaseStorageHook) data.getStorageHook(BaseStorageHook.KEY);
+ try {
+ storageHook.delete(postpone, BaseStorageHook.DEL_BUNDLE_STORE);
+ } catch (IOException e) {
+ // nothing we can do
+ }
+ storage.processExtension(data, BaseStorage.EXTENSION_UNINSTALLED);
+ data.setLastModified(System.currentTimeMillis());
+ storage.updateState(data, BundleEvent.UNINSTALLED);
+ }
+
+ /**
+ * Undo the change to persistent storage.
+ *
+ * @throws BundleException If a failure occured modifiying peristent storage.
+ */
+ public void undo() throws BundleException {
+ // do nothing
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUpdate.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUpdate.java
new file mode 100644
index 000000000..d605bbed7
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUpdate.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.baseadaptor;
+
+import java.io.*;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Dictionary;
+import org.eclipse.osgi.baseadaptor.*;
+import org.eclipse.osgi.baseadaptor.hooks.StorageHook;
+import org.eclipse.osgi.framework.adaptor.BundleData;
+import org.eclipse.osgi.framework.adaptor.BundleOperation;
+import org.eclipse.osgi.framework.internal.core.ReferenceInputStream;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.*;
+
+public class BundleUpdate implements BundleOperation {
+ private BaseData data;
+ private BaseData newData;
+ private URLConnection source;
+ private BaseStorage storage;
+
+ public BundleUpdate(BaseData data, URLConnection source, BaseStorage storage) {
+ this.data = data;
+ this.source = source;
+ this.storage = storage;
+ }
+
+ /**
+ * Perform the change to persistent storage.
+ *
+ * @return Bundle object for the target bundle.
+ * @throws BundleException if an error occurs
+ */
+ public BundleData begin() throws BundleException {
+ try {
+ newData = storage.createBaseData(data.getBundleID(), data.getLocation());
+ newData.setLastModified(System.currentTimeMillis());
+ newData.setStartLevel(data.getStartLevel());
+ newData.setStatus(data.getStatus());
+ // load the storage hooks into the new data
+ StorageHook[] storageHooks = data.getAdaptor().getHookRegistry().getStorageHooks();
+ StorageHook[] instanceHooks = new StorageHook[storageHooks.length];
+ for (int i = 0; i < storageHooks.length; i++) {
+ instanceHooks[i] = storageHooks[i].create(newData);
+ instanceHooks[i].copy(data.getStorageHook((String) instanceHooks[i].getKey()));
+ }
+ newData.setStorageHooks(instanceHooks);
+ // get the old and new eclipse storage hooks
+ BaseStorageHook oldStorageHook = (BaseStorageHook) data.getStorageHook(BaseStorageHook.KEY);
+ BaseStorageHook newStorageHook = (BaseStorageHook) newData.getStorageHook(BaseStorageHook.KEY);
+ InputStream in = source.getInputStream();
+ URL sourceURL = source.getURL();
+ String protocol = sourceURL == null ? null : sourceURL.getProtocol();
+ try {
+ if (in instanceof ReferenceInputStream) {
+ URL reference = ((ReferenceInputStream) in).getReference();
+ if (!"file".equals(reference.getProtocol())) //$NON-NLS-1$
+ throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_URL_CREATE_EXCEPTION, reference));
+ // check to make sure we are not just trying to update to the same
+ // directory reference. This would be a no-op.
+ String path = reference.getPath();
+ if (path.equals(oldStorageHook.getFileName()))
+ throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_SAME_REF_UPDATE, reference));
+ newStorageHook.setReference(true);
+ newStorageHook.setFileName(path);
+ } else {
+ File genDir = newStorageHook.createGenerationDir();
+ if (!genDir.exists())
+ throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_DIRECTORY_CREATE_EXCEPTION, genDir.getPath()));
+ newStorageHook.setReference(false);
+ newStorageHook.setFileName(BaseStorage.BUNDLEFILE_NAME);
+ File outFile = new File(genDir, newStorageHook.getFileName());
+ if ("file".equals(protocol)) { //$NON-NLS-1$
+ File inFile = new File(source.getURL().getPath());
+ if (inFile.isDirectory()) {
+ AdaptorUtil.copyDir(inFile, outFile);
+ } else {
+ AdaptorUtil.readFile(in, outFile);
+ }
+ } else {
+ AdaptorUtil.readFile(in, outFile);
+ }
+ }
+ Dictionary manifest = storage.loadManifest(newData, true);
+ for (int i = 0; i < instanceHooks.length; i++)
+ instanceHooks[i].initialize(manifest);
+ } finally {
+ try {
+ if (in != null)
+ in.close();
+ } catch (IOException ee) {
+ // nothing to do here
+ }
+ }
+ } catch (IOException e) {
+ throw new BundleException(AdaptorMsg.BUNDLE_READ_EXCEPTION, e);
+ }
+
+ return (newData);
+ }
+
+ /**
+ * Commit the change to persistent storage.
+ *
+ * @param postpone If true, the bundle's persistent
+ * storage cannot be immediately reclaimed.
+ * @throws BundleException If a failure occured modifiying peristent storage.
+ */
+
+ public void commit(boolean postpone) throws BundleException {
+ storage.processExtension(data, BaseStorage.EXTENSION_UNINSTALLED); // remove the old extension
+ storage.processExtension(newData, BaseStorage.EXTENSION_UPDATED); // update to the new one
+ try {
+ newData.setLastModified(System.currentTimeMillis());
+ newData.save();
+ } catch (IOException e) {
+ throw new BundleException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION, e);
+ }
+ storage.updateState(newData, BundleEvent.UPDATED);
+ BaseStorageHook oldStorageHook = (BaseStorageHook) data.getStorageHook(BaseStorageHook.KEY);
+ try {
+ oldStorageHook.delete(postpone, BaseStorageHook.DEL_GENERATION);
+ } catch (IOException e) {
+ data.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, data.getBundle(), e);
+ }
+ }
+
+ /**
+ * Undo the change to persistent storage.
+ *
+ * @throws BundleException If a failure occured modifiying peristent storage.
+ */
+ public void undo() throws BundleException {
+ if (newData != null) {
+ BaseStorageHook newStorageHook = (BaseStorageHook) newData.getStorageHook(BaseStorageHook.KEY);
+ try {
+ if (newStorageHook != null)
+ newStorageHook.delete(false, BaseStorageHook.DEL_GENERATION);
+ } catch (IOException e) {
+ data.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, data.getBundle(), e);
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader.java
new file mode 100644
index 000000000..7c4ee7a82
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/DefaultClassLoader.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.baseadaptor;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.*;
+import java.security.cert.Certificate;
+import java.util.Enumeration;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
+import org.eclipse.osgi.baseadaptor.loader.*;
+import org.eclipse.osgi.framework.adaptor.BundleData;
+import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
+import org.eclipse.osgi.framework.debug.Debug;
+
+/**
+ * The default implemention of <code>BaseClassLoader</code>. This implementation extends
+ * <code>ClassLoader</code>.
+ * @see BaseClassLoader
+ * @see ClasspathManager
+ */
+public class DefaultClassLoader extends ClassLoader implements BaseClassLoader {
+ /**
+ * A PermissionCollection for AllPermissions; shared across all ProtectionDomains when security is disabled
+ */
+ protected static final PermissionCollection ALLPERMISSIONS;
+ static {
+ AllPermission allPerm = new AllPermission();
+ ALLPERMISSIONS = allPerm.newPermissionCollection();
+ if (ALLPERMISSIONS != null)
+ ALLPERMISSIONS.add(allPerm);
+ }
+
+ protected ClassLoaderDelegate delegate;
+ protected ProtectionDomain domain;
+ protected ClasspathManager manager;
+
+ /**
+ * Constructs a new DefaultClassLoader.
+ * @param parent the parent classloader
+ * @param delegate the delegate for this classloader
+ * @param domain the domain for this classloader
+ * @param bundledata the bundledata for this classloader
+ * @param classpath the classpath for this classloader
+ */
+ public DefaultClassLoader(ClassLoader parent, ClassLoaderDelegate delegate, ProtectionDomain domain, BaseData bundledata, String[] classpath) {
+ super(parent);
+ this.delegate = delegate;
+ this.domain = domain;
+ this.manager = new ClasspathManager(bundledata, classpath, this);
+ }
+
+ /**
+ * Loads a class for the bundle. First delegate.findClass(name) is called.
+ * The delegate will query the system class loader, bundle imports, bundle
+ * local classes, bundle hosts and fragments. The delegate will call
+ * BundleClassLoader.findLocalClass(name) to find a class local to this
+ * bundle.
+ * @param name the name of the class to load.
+ * @param resolve indicates whether to resolve the loaded class or not.
+ * @return The Class object.
+ * @throws ClassNotFoundException if the class is not found.
+ */
+ protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ if (Debug.DEBUG && Debug.DEBUG_LOADER)
+ Debug.println("BundleClassLoader[" + delegate + "].loadClass(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
+ try {
+ // Just ask the delegate. This could result in findLocalClass(name) being called.
+ Class clazz = delegate.findClass(name);
+ // resolve the class if asked to.
+ if (resolve)
+ resolveClass(clazz);
+ return (clazz);
+ } catch (Error e) {
+ if (Debug.DEBUG && Debug.DEBUG_LOADER) {
+ Debug.println("BundleClassLoader[" + delegate + "].loadClass(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Debug.printStackTrace(e);
+ }
+ throw e;
+ } catch (ClassNotFoundException e) {
+ // If the class is not found do not try to look for it locally.
+ // The delegate would have already done that for us.
+ if (Debug.DEBUG && Debug.DEBUG_LOADER) {
+ Debug.println("BundleClassLoader[" + delegate + "].loadClass(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Debug.printStackTrace(e);
+ }
+ throw e;
+ }
+ }
+
+ /**
+ * Gets a resource for the bundle. First delegate.findResource(name) is
+ * called. The delegate will query the system class loader, bundle imports,
+ * bundle local resources, bundle hosts and fragments. The delegate will
+ * call BundleClassLoader.findLocalResource(name) to find a resource local
+ * to this bundle.
+ * @param name The resource path to get.
+ * @return The URL of the resource or null if it does not exist.
+ */
+ public URL getResource(String name) {
+ if (Debug.DEBUG && Debug.DEBUG_LOADER) {
+ Debug.println("BundleClassLoader[" + delegate + "].getResource(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ URL url = delegate.findResource(name);
+ if (url != null)
+ return (url);
+
+ if (Debug.DEBUG && Debug.DEBUG_LOADER) {
+ Debug.println("BundleClassLoader[" + delegate + "].getResource(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ return (null);
+ }
+
+ /**
+ * Finds all resources with the specified name. This method must call
+ * delegate.findResources(name) to find all the resources.
+ * @param name The resource path to find.
+ * @return An Enumeration of all resources found or null if the resource.
+ * @throws IOException
+ */
+ protected Enumeration findResources(String name) throws IOException {
+ return (delegate.findResources(name));
+ }
+
+ /**
+ * Finds a library for this bundle. Simply calls
+ * delegate.findLibrary(libname) to find the library.
+ * @param libname The library to find.
+ * @return The URL of the resource or null if it does not exist.
+ */
+ protected String findLibrary(String libname) {
+ return delegate.findLibrary(libname);
+ }
+
+ public ProtectionDomain getDomain() {
+ return domain;
+ }
+
+ public ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain cpDomain) {
+ return new ClasspathEntry(bundlefile, createProtectionDomain(bundlefile, cpDomain));
+ }
+
+ public Class defineClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry) {
+ return defineClass(name, classbytes, 0, classbytes.length, classpathEntry.getDomain());
+ }
+
+ public Class publicFindLoaded(String classname) {
+ return findLoadedClass(classname);
+ }
+
+ public Object publicGetPackage(String pkgname) {
+ return getPackage(pkgname);
+ }
+
+ public Object publicDefinePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) {
+ return definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase);
+ }
+
+ public void initialize() {
+ manager.initialize();
+ }
+
+ public URL findLocalResource(String resource) {
+ return manager.findLocalResource(resource);
+ }
+
+ public Enumeration findLocalResources(String resource) {
+ return manager.findLocalResources(resource);
+ }
+
+ public Class findLocalClass(String classname) throws ClassNotFoundException {
+ return manager.findLocalClass(classname);
+ }
+
+ public void close() {
+ manager.close();
+ }
+
+ public void attachFragment(BundleData sourcedata, ProtectionDomain sourcedomain, String[] sourceclasspath) {
+ manager.attachFragment(sourcedata, sourcedomain, sourceclasspath);
+ }
+
+ public ClassLoaderDelegate getDelegate() {
+ return delegate;
+ }
+
+ /**
+ * Creates a ProtectionDomain which uses specified BundleFile and the permissions of the baseDomain
+ * @param bundlefile The source bundlefile the domain is for.
+ * @param baseDomain The source domain.
+ * @return a ProtectionDomain which uses specified BundleFile and the permissions of the baseDomain
+ */
+ public static ProtectionDomain createProtectionDomain(BundleFile bundlefile, ProtectionDomain baseDomain) {
+ // create a protection domain which knows about the codesource for this classpath entry (bug 89904)
+ try {
+ // use the permissions supplied by the domain passed in from the framework
+ PermissionCollection permissions;
+ if (baseDomain != null)
+ permissions = baseDomain.getPermissions();
+ else
+ // no domain specified. Better use a collection that has all permissions
+ // this is done just incase someone sets the security manager later
+ permissions = ALLPERMISSIONS;
+ return new ClasspathDomain(bundlefile.getBaseFile().toURL(), permissions);
+ } catch (MalformedURLException e) {
+ // Failed to create our own domain; just return the baseDomain
+ return baseDomain;
+ }
+ }
+
+ /**
+ * Very simple protection domain that uses a URL to create a CodeSource for a ProtectionDomain
+ */
+ protected static class ClasspathDomain extends ProtectionDomain {
+ public ClasspathDomain(URL codeLocation, PermissionCollection permissions) {
+ super(new CodeSource(codeLocation, (Certificate[]) null), permissions);
+ }
+ }
+
+ public ClasspathManager getClasspathManager() {
+ return manager;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/DevClassLoadingHook.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/DevClassLoadingHook.java
new file mode 100644
index 000000000..b0befb8f8
--- /dev/null
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/DevClassLoadingHook.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osgi.internal.baseadaptor;
+
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import org.eclipse.osgi.baseadaptor.*;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook;
+import org.eclipse.osgi.baseadaptor.loader.*;
+import org.eclipse.osgi.framework.adaptor.BundleProtectionDomain;
+import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
+
+public class DevClassLoadingHook implements ClassLoadingHook, HookConfigurator {
+
+ public byte[] processClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
+ // Do nothing
+ return null;
+ }
+
+ public boolean addClassPathEntry(ArrayList cpEntries, String cp, ClasspathManager hostmanager, BaseData sourcedata, ProtectionDomain sourcedomain) {
+ String[] devClassPath = !DevClassPathHelper.inDevelopmentMode() ? null : DevClassPathHelper.getDevClassPath(sourcedata.getSymbolicName());
+ if (devClassPath == null || devClassPath.length == 0)
+ return false; // not in dev mode return
+ boolean result = false;
+ for (int i = 0; i < devClassPath.length; i++) {
+ if (ClasspathManager.addClassPathEntry(cpEntries, devClassPath[i], hostmanager, sourcedata, sourcedomain))
+ result = true;
+ else {
+ // if in dev mode, try using the cp as an absolute path
+ ClasspathEntry entry = hostmanager.getExternalClassPath(devClassPath[i], sourcedata, sourcedomain);
+ if (entry != null){
+ cpEntries.add(entry);
+ result = true;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ public String findLibrary(BaseData data, String libName) {
+ // Do nothing
+ return null;
+ }
+
+ public ClassLoader getBundleClassLoaderParent() {
+ // Do nothing
+ return null;
+ }
+
+ public BaseClassLoader createClassLoader(ClassLoader parent, ClassLoaderDelegate delegate, BundleProtectionDomain domain, BaseData data, String[] bundleclasspath) {
+ // do nothing
+ return null;
+ }
+
+ public void initializedClassLoader(BaseClassLoader baseClassLoader, BaseData data) {
+ // do nothing
+ }
+
+ public void addHooks(HookRegistry hookRegistry) {
+ if (DevClassPathHelper.inDevelopmentMode())
+ // only add dev classpath manager if in dev mode
+ hookRegistry.addClassLoadingHook(new DevClassLoadingHook());
+
+ }
+}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/DevClassPathHelper.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/DevClassPathHelper.java
index b027bfc1b..de565abbb 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/DevClassPathHelper.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/DevClassPathHelper.java
@@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
-package org.eclipse.osgi.framework.adaptor.core;
+package org.eclipse.osgi.internal.baseadaptor;
import java.io.IOException;
import java.io.InputStream;
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/ExternalMessages.properties b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/ExternalMessages.properties
index d1d9a8e6d..d1d9a8e6d 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/ExternalMessages.properties
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/ExternalMessages.properties
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/InvalidVersion.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/InvalidVersion.java
index 19670799a..a2edb6520 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/InvalidVersion.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/InvalidVersion.java
@@ -9,7 +9,7 @@
* IBM Corporation - initial API and implementation
*******************************************************************************/
-package org.eclipse.osgi.framework.adaptor.core;
+package org.eclipse.osgi.internal.baseadaptor;
import org.osgi.framework.Version;
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/StateManager.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/StateManager.java
index 05df80888..7a039bab0 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/adaptor/core/StateManager.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/StateManager.java
@@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
-package org.eclipse.osgi.framework.adaptor.core;
+package org.eclipse.osgi.internal.baseadaptor;
import java.io.File;
import java.io.IOException;
@@ -60,7 +60,6 @@ public class StateManager implements PlatformAdmin, Runnable {
private StateImpl systemState;
private StateObjectFactoryImpl factory;
private long lastTimeStamp;
- private BundleInstaller installer;
private boolean cachedState = false;
private File stateFile;
private File lazyFile;
@@ -270,25 +269,7 @@ public class StateManager implements PlatformAdmin, Runnable {
* @see PlatformAdmin#commit(State)
*/
public synchronized void commit(State state) throws BundleException {
- // no installer have been provided - commit not supported
- if (installer == null)
- throw new IllegalArgumentException("PlatformAdmin.commit() not supported"); //$NON-NLS-1$
- if (!(state instanceof UserState))
- throw new IllegalArgumentException("Wrong state implementation"); //$NON-NLS-1$
- if (state.getTimeStamp() != systemState.getTimeStamp())
- throw new BundleException(StateMsg.COMMIT_INVALID_TIMESTAMP);
- StateDelta delta = state.compare(systemState);
- BundleDelta[] changes = delta.getChanges();
- for (int i = 0; i < changes.length; i++)
- if ((changes[i].getType() & BundleDelta.ADDED) > 0)
- installer.installBundle(changes[i].getBundle());
- else if ((changes[i].getType() & BundleDelta.REMOVED) > 0)
- installer.uninstallBundle(changes[i].getBundle());
- else if ((changes[i].getType() & BundleDelta.UPDATED) > 0)
- installer.updateBundle(changes[i].getBundle());
- else {
- // bug in StateDelta#getChanges
- }
+ throw new IllegalArgumentException("PlatformAdmin.commit() not supported"); //$NON-NLS-1$
}
/**
@@ -309,23 +290,6 @@ public class StateManager implements PlatformAdmin, Runnable {
return StateHelperImpl.getInstance();
}
- /**
- * Returns the bundle installer.
- * @return the bundle installer
- */
- public BundleInstaller getInstaller() {
- return installer;
- }
-
- /**
- * Sets the bundle installer. The bundle installer will be used when a state is commited
- * using the commit(State) method.
- * @param installer the bundle installer
- */
- public void setInstaller(BundleInstaller installer) {
- this.installer = installer;
- }
-
public void run() {
long timeStamp = lastTimeStamp; // cache the original timestamp incase of updates
while (true) {
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/SystemBundleData.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/SystemBundleData.java
index 9fc001b34..36e9c6f19 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/framework/internal/core/SystemBundleData.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/SystemBundleData.java
@@ -4,28 +4,31 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
-package org.eclipse.osgi.framework.internal.core;
+package org.eclipse.osgi.internal.baseadaptor;
import java.io.*;
import java.net.URL;
import java.util.Enumeration;
+import org.eclipse.osgi.baseadaptor.*;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
import org.eclipse.osgi.framework.adaptor.*;
-import org.eclipse.osgi.framework.adaptor.core.*;
import org.eclipse.osgi.framework.debug.Debug;
import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
import org.eclipse.osgi.framework.util.Headers;
import org.osgi.framework.BundleException;
-public class SystemBundleData extends AbstractBundleData {
- public static final String OSGI_FRAMEWORK = "osgi.framework"; //$NON-NLS-1$
+public class SystemBundleData extends BaseData {
+ private static final String OSGI_FRAMEWORK = "osgi.framework"; //$NON-NLS-1$
- public SystemBundleData(AbstractFrameworkAdaptor adaptor) throws BundleException {
- super(adaptor, 0);
+ public SystemBundleData(BaseAdaptor adaptor) throws BundleException {
+ super(0, adaptor);
File osgiBase = getOsgiBase();
createBundleFile(osgiBase);
manifest = createManifest(osgiBase);
@@ -34,7 +37,7 @@ public class SystemBundleData extends AbstractBundleData {
}
private File getOsgiBase() {
- String frameworkLocation = FrameworkProperties.getProperty(OSGI_FRAMEWORK);
+ String frameworkLocation = FrameworkProperties.getProperty(SystemBundleData.OSGI_FRAMEWORK);
if (frameworkLocation != null)
// TODO assumes the location is a file URL
return new File(frameworkLocation.substring(5));
@@ -54,43 +57,27 @@ public class SystemBundleData extends AbstractBundleData {
private Headers createManifest(File osgiBase) throws BundleException {
InputStream in = null;
- if (osgiBase != null && osgiBase.exists()) {
+ if (osgiBase != null && osgiBase.exists())
try {
- BundleEntry entry = baseBundleFile.getEntry(Constants.OSGI_BUNDLE_MANIFEST);
+ BundleEntry entry = getBundleFile().getEntry(Constants.OSGI_BUNDLE_MANIFEST);
if (entry != null)
in = entry.getInputStream();
} catch (IOException e) {
// do nothing here. in == null
}
- }
// If we cannot find the Manifest file from the baseBundleFile then
// search for the manifest as a classloader resource
// This allows an adaptor to package the SYSTEMBUNDLE.MF file in a jar.
- if (in == null) {
+ if (in == null)
in = getManifestAsResource();
- }
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- if (in == null) {
+ if (Debug.DEBUG && Debug.DEBUG_GENERAL)
+ if (in == null)
Debug.println("Unable to find system bundle manifest " + Constants.OSGI_BUNDLE_MANIFEST); //$NON-NLS-1$
- }
- }
if (in == null)
throw new BundleException(AdaptorMsg.SYSTEMBUNDLE_MISSING_MANIFEST);
- Headers systemManifest = Headers.parseManifest(in);
- // now get any extra packages and services that the adaptor wants
- // to export and merge this into the system bundle's manifest
- String exportPackages = adaptor.getExportPackages();
- String exportServices = adaptor.getExportServices();
- String providePackages = adaptor.getProvidePackages();
- if (exportPackages != null)
- appendManifestValue(systemManifest, Constants.EXPORT_PACKAGE, exportPackages);
- if (exportServices != null)
- appendManifestValue(systemManifest, Constants.EXPORT_SERVICE, exportServices);
- if (providePackages != null)
- appendManifestValue(systemManifest, Constants.PROVIDE_PACKAGE, providePackages);
- return systemManifest;
+ return Headers.parseManifest(in);
}
private InputStream getManifestAsResource() {
@@ -115,26 +102,16 @@ public class SystemBundleData extends AbstractBundleData {
return null;
}
- private void appendManifestValue(Headers systemManifest, String header, String append) {
- String newValue = (String) systemManifest.get(header);
- if (newValue == null) {
- newValue = append;
- } else {
- newValue += "," + append; //$NON-NLS-1$
- }
- systemManifest.set(header, newValue, true);
- }
-
private void createBundleFile(File osgiBase) {
if (osgiBase != null)
try {
- baseBundleFile = adaptor.createBundleFile(osgiBase, this);
+ bundleFile = getAdaptor().createBundleFile(osgiBase, this);
} catch (IOException e) {
// should not happen
}
else
- baseBundleFile = new BundleFile(osgiBase) {
- public File getFile(String path) {
+ bundleFile = new BundleFile(osgiBase) {
+ public File getFile(String path, boolean nativeCode) {
return null;
}
@@ -162,7 +139,7 @@ public class SystemBundleData extends AbstractBundleData {
private void setMetaData() throws BundleException {
setLocation(Constants.SYSTEM_BUNDLE_LOCATION);
- loadFromManifest();
+ BaseStorageHook.loadManifest(this, manifest);
}
public BundleClassLoader createClassLoader(ClassLoaderDelegate delegate, BundleProtectionDomain domain, String[] bundleclasspath) {
@@ -197,7 +174,4 @@ public class SystemBundleData extends AbstractBundleData {
// do nothing
}
- public String[] getBundleSigners() {
- return null; // system bundle cannot be signed
- }
}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/ADAPTOR.MF b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/ADAPTOR.MF
deleted file mode 100644
index 9537d5ea2..000000000
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/ADAPTOR.MF
+++ /dev/null
@@ -1,8 +0,0 @@
-Export-Service:
- org.eclipse.osgi.framework.log.FrameworkLog,
- org.eclipse.osgi.service.environment.EnvironmentInfo,
- org.eclipse.osgi.service.pluginconversion.PluginConverter,
- org.eclipse.osgi.service.datalocation.Location,
- org.eclipse.osgi.service.runnable,
- org.eclipse.osgi.service.urlconversion.URLConverter,
- org.eclipse.osgi.service.localization.BundleLocalization
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java
deleted file mode 100644
index 8e10d4074..000000000
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptor.java
+++ /dev/null
@@ -1,982 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2006 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.core.runtime.adaptor;
-
-import java.io.*;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.*;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.SAXParserFactory;
-import org.eclipse.core.runtime.internal.adaptor.*;
-import org.eclipse.core.runtime.internal.stats.StatsManager;
-import org.eclipse.osgi.framework.adaptor.*;
-import org.eclipse.osgi.framework.adaptor.core.*;
-import org.eclipse.osgi.framework.console.CommandProvider;
-import org.eclipse.osgi.framework.debug.Debug;
-import org.eclipse.osgi.framework.debug.FrameworkDebugOptions;
-import org.eclipse.osgi.framework.internal.core.Constants;
-import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
-import org.eclipse.osgi.framework.log.FrameworkLog;
-import org.eclipse.osgi.framework.log.FrameworkLogEntry;
-import org.eclipse.osgi.service.datalocation.Location;
-import org.eclipse.osgi.service.pluginconversion.PluginConverter;
-import org.eclipse.osgi.service.resolver.*;
-import org.eclipse.osgi.service.runnable.ApplicationLauncher;
-import org.eclipse.osgi.service.urlconversion.URLConverter;
-import org.eclipse.osgi.storagemanager.ManagedOutputStream;
-import org.eclipse.osgi.storagemanager.StorageManager;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.*;
-
-/**
- * The FrameworkAdaptor implementation used to launch to OSGi framework for Eclipse.
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.1
- */
-public class EclipseAdaptor extends AbstractFrameworkAdaptor {
- /** System property used to clean the osgi configuration area */
- public static final String PROP_CLEAN = "osgi.clean"; //$NON-NLS-1$
- /** System property used to prevent VM exit when unexpected errors occur */
- public static final String PROP_EXITONERROR = "eclipse.exitOnError"; //$NON-NLS-1$
- /** System property used to determine whether State saver needs to be enabled */
- public static final String PROP_ENABLE_STATE_SAVER = "eclipse.enableStateSaver"; //$NON-NLS-1$
-
- static final String F_LOG = ".log"; //$NON-NLS-1$
- /** Manifest header used to specify the plugin class */
- // TODO rename it to Eclipse-PluginClass
- public static final String PLUGIN_CLASS = "Plugin-Class"; //$NON-NLS-1$
- /** Manifest header used to specify the lazy start properties of a bundle */
- public static final String ECLIPSE_LAZYSTART = "Eclipse-LazyStart"; //$NON-NLS-1$
- /** An Eclipse-LazyStart attribute used to specify exception classes for auto start */
- public static final String ECLIPSE_LAZYSTART_EXCEPTIONS = "exceptions"; //$NON-NLS-1$
- /**
- * Manifest header used to specify the auto start properties of a bundle
- * @deprecated use {@link #ECLIPSE_LAZYSTART}
- */
- public static final String ECLIPSE_AUTOSTART = "Eclipse-AutoStart"; //$NON-NLS-1$
- /**
- * @deprecated use {@link #ECLIPSE_LAZYSTART_EXCEPTIONS}
- */
- public static final String ECLIPSE_AUTOSTART_EXCEPTIONS = ECLIPSE_LAZYSTART_EXCEPTIONS;
- /** The SAX factory name */
- public static final String SAXFACTORYNAME = "javax.xml.parsers.SAXParserFactory"; //$NON-NLS-1$
- /** The DOM factory name */
- public static final String DOMFACTORYNAME = "javax.xml.parsers.DocumentBuilderFactory"; //$NON-NLS-1$
-
- private static final String RUNTIME_ADAPTOR = FRAMEWORK_SYMBOLICNAME + "/eclipseadaptor"; //$NON-NLS-1$
-
- private static final String OPTION_PLATFORM_ADMIN = RUNTIME_ADAPTOR + "/debug/platformadmin"; //$NON-NLS-1$
-
- private static final String OPTION_PLATFORM_ADMIN_RESOLVER = RUNTIME_ADAPTOR + "/debug/platformadmin/resolver"; //$NON-NLS-1$
-
- private static final String OPTION_MONITOR_PLATFORM_ADMIN = RUNTIME_ADAPTOR + "/resolver/timing"; //$NON-NLS-1$
-
- private static final String OPTION_RESOLVER_READER = RUNTIME_ADAPTOR + "/resolver/reader/timing"; //$NON-NLS-1$
-
- private static final String OPTION_CONVERTER = RUNTIME_ADAPTOR + "/converter/debug"; //$NON-NLS-1$
-
- private static final String OPTION_LOCATION = RUNTIME_ADAPTOR + "/debug/location"; //$NON-NLS-1$
-
- /** The current bundle data version */
- public static final byte BUNDLEDATA_VERSION = 16;
- /** The NULL tag used in bundle data */
- public static final byte NULL = 0;
- /** The OBJECT tag used in bundle data */
- public static final byte OBJECT = 1;
-
- private static EclipseAdaptor instance;
-
- private byte cacheVersion;
-
- private long timeStamp = 0;
-
- // assume a file: installURL
- private String installPath = null;
-
- private boolean exitOnError = true;
-
- private BundleStopper stopper;
-
- private StorageManager storageManager;
-
- private boolean reinitialize = false;
-
- private StateSaver stateSaver = null;
- private boolean noXML = false;
-
- /**
- * Should be instantiated only by the framework (through reflection).
- * @param args the adaptor arguments
- */
- public EclipseAdaptor(String[] args) {
- super(args);
- instance = this;
- setDebugOptions();
- }
-
- /**
- * Gets the default instance
- * @return the default instance
- */
- public static EclipseAdaptor getDefault() {
- return instance;
- }
-
- private FrameworkLog createPerformanceLog() {
- String logFileProp = FrameworkProperties.getProperty(EclipseStarter.PROP_LOGFILE);
- if (logFileProp != null) {
- int lastSlash = logFileProp.lastIndexOf(File.separatorChar);
- if (lastSlash > 0) {
- String logFile = logFileProp.substring(0, lastSlash + 1) + "performance.log"; //$NON-NLS-1$
- return new EclipseLog(new File(logFile));
- }
- }
- //if all else fails, write to std err
- return new EclipseLog(new PrintWriter(System.err));
- }
-
- /**
- * @see FrameworkAdaptor#initialize(EventPublisher)
- */
- public void initialize(EventPublisher publisher) {
- if (Boolean.valueOf(FrameworkProperties.getProperty(EclipseAdaptor.PROP_CLEAN)).booleanValue())
- cleanOSGiCache();
- boolean readOnlyConfiguration = LocationManager.getConfigurationLocation().isReadOnly();
- storageManager = initStorageManager(LocationManager.getOSGiConfigurationDir(), readOnlyConfiguration ? "none" : null, readOnlyConfiguration); //$NON-NLS-1$
- readHeaders();
- super.initialize(publisher);
- // default the bootdelegation to all packages
- if (FrameworkProperties.getProperty(Constants.OSGI_BOOTDELEGATION) == null && !Constants.OSGI_BOOTDELEGATION_NONE.equals(FrameworkProperties.getProperty(Constants.OSGI_JAVA_PROFILE_BOOTDELEGATION)))
- FrameworkProperties.setProperty(Constants.OSGI_BOOTDELEGATION, "*"); //$NON-NLS-1$
- if (FrameworkProperties.getProperty(Constants.ECLIPSE_EE_INSTALL_VERIFY) == null)
- FrameworkProperties.setProperty(Constants.ECLIPSE_EE_INSTALL_VERIFY, "false"); //$NON-NLS-1$
- // we need to set the install path as soon as possible so we can determine
- // the absolute location of install relative URLs
- Location installLoc = LocationManager.getInstallLocation();
- if (installLoc != null) {
- URL installURL = installLoc.getURL();
- // assume install URL is file: based
- installPath = installURL.getPath();
- }
- }
-
- /**
- * @see AbstractFrameworkAdaptor#initializeMetadata()
- */
- public void initializeMetadata() {
- // do nothing here; metadata is already initialized by readHeaders.
- }
-
- protected void initBundleStoreRootDir() {
- File configurationLocation = LocationManager.getOSGiConfigurationDir();
- if (configurationLocation != null) {
- bundleStoreRootDir = new File(configurationLocation, LocationManager.BUNDLES_DIR);
- bundleStore = bundleStoreRootDir.getAbsolutePath();
- } else {
- // last resort just default to "bundles"
- bundleStore = LocationManager.BUNDLES_DIR;
- bundleStoreRootDir = new File(bundleStore);
- }
-
- /* store bundleStore back into adaptor properties for others to see */
- properties.put(BUNDLE_STORE, bundleStoreRootDir.getAbsolutePath());
- }
-
- protected FrameworkLog createFrameworkLog() {
- if (frameworkLog != null)
- return frameworkLog;
- return EclipseStarter.createFrameworkLog();
- }
-
- private File[] findStateFiles() {
- if (reinitialize)
- return new File[2]; // return null enties to indicate reinitialize
- File stateFile = null;
- File lazyFile = null;
- try {
- stateFile = storageManager.lookup(LocationManager.STATE_FILE, false);
- lazyFile = storageManager.lookup(LocationManager.LAZY_FILE, false);
- } catch (IOException ex) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Error reading state file " + ex.getMessage()); //$NON-NLS-1$
- Debug.printStackTrace(ex);
- }
- }
- //if it does not exist, try to read it from the parent
- if (stateFile == null || !stateFile.isFile()) { // NOTE this check is redundant since it
- // is done in StateManager, however it
- // is more convenient to have it here
- Location parentConfiguration = null;
- Location currentConfiguration = LocationManager.getConfigurationLocation();
- if (currentConfiguration != null && (parentConfiguration = currentConfiguration.getParentLocation()) != null) {
- try {
- File stateLocationDir = new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME);
- StorageManager newStorageManager = initStorageManager(stateLocationDir, "none", true); //$NON-NLS-1$);
- stateFile = newStorageManager.lookup(LocationManager.STATE_FILE, false);
- lazyFile = newStorageManager.lookup(LocationManager.LAZY_FILE, false);
- } catch (IOException ex) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Error reading state file " + ex.getMessage()); //$NON-NLS-1$
- Debug.printStackTrace(ex);
- }
- }
- } else {
- try {
- //it did not exist in either place, so create it in the original location
- if (canWrite()) {
- stateFile = storageManager.lookup(LocationManager.STATE_FILE, true);
- lazyFile = storageManager.lookup(LocationManager.LAZY_FILE, true);
- }
- } catch (IOException ex) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Error reading state file " + ex.getMessage()); //$NON-NLS-1$
- Debug.printStackTrace(ex);
- }
- }
- }
- }
- return new File[] {stateFile, lazyFile};
- }
-
- protected StateManager createStateManager() {
- File[] stateFiles = findStateFiles();
- File stateFile = stateFiles[0];
- File lazyFile = stateFiles[1];
-
- stateManager = new StateManager(stateFile, lazyFile, context, timeStamp);
- stateManager.setInstaller(new EclipseBundleInstaller(context));
- State systemState = null;
- if (!invalidState) {
- systemState = stateManager.readSystemState();
- if (systemState != null)
- return stateManager;
- }
- systemState = stateManager.createSystemState();
- Bundle[] installedBundles = context.getBundles();
- if (installedBundles == null)
- return stateManager;
- StateObjectFactory factory = stateManager.getFactory();
- for (int i = 0; i < installedBundles.length; i++) {
- Bundle toAdd = installedBundles[i];
- try {
- Dictionary toAddManifest = toAdd.getHeaders(""); //$NON-NLS-1$
- // if this is a cached manifest need to get the real one
- if (toAddManifest instanceof CachedManifest)
- toAddManifest = ((CachedManifest) toAddManifest).getManifest();
- BundleDescription newDescription = factory.createBundleDescription(systemState, toAddManifest, toAdd.getLocation(), toAdd.getBundleId());
- systemState.addBundle(newDescription);
- } catch (BundleException be) {
- // just ignore bundle datas with invalid manifests
- }
- }
- // we need the state resolved
- systemState.setTimeStamp(timeStamp);
- systemState.resolve();
- invalidState = false;
- return stateManager;
- }
-
- public void shutdownStateManager() {
- if (stateSaver != null)
- stateSaver.shutdown();
- saveStateToFile(true);
- // calling stateManager.shutdown from saveStateToFile will also stop the data manager
- // but we may not call that method if the configuration is read-only or if the state has not changed,
- // so we call here also just in case.
- stateManager.stopDataManager();
- }
-
- void saveStateToFile(boolean shutdown) {
- if (!canWrite() || !stateManager.saveNeeded())
- return;
- try {
- File stateTmpFile = File.createTempFile(LocationManager.STATE_FILE, ".new", LocationManager.getOSGiConfigurationDir()); //$NON-NLS-1$
- File lazyTmpFile = File.createTempFile(LocationManager.LAZY_FILE, ".new", LocationManager.getOSGiConfigurationDir()); //$NON-NLS-1$
- if (shutdown)
- stateManager.shutdown(stateTmpFile, lazyTmpFile);
- else
- synchronized (stateManager) {
- stateManager.update(stateTmpFile, lazyTmpFile);
- }
- storageManager.lookup(LocationManager.STATE_FILE, true);
- storageManager.lookup(LocationManager.LAZY_FILE, true);
- storageManager.update(new String[] {LocationManager.STATE_FILE, LocationManager.LAZY_FILE}, new String[] {stateTmpFile.getName(), lazyTmpFile.getName()});
- } catch (IOException e) {
- frameworkLog.log(new FrameworkEvent(FrameworkEvent.ERROR, context.getBundle(), e));
- }
- }
-
- private void cleanOSGiCache() {
- File osgiConfig = LocationManager.getOSGiConfigurationDir();
- if (!rm(osgiConfig)) {
- // TODO log error?
- }
- }
-
- private void readHeaders() {
- InputStream bundleDataStream = findBundleDataFile();
- if (bundleDataStream == null)
- return;
-
- try {
- DataInputStream in = new DataInputStream(new BufferedInputStream(bundleDataStream));
- try {
- cacheVersion = in.readByte();
- if (cacheVersion == BUNDLEDATA_VERSION) {
- timeStamp = in.readLong();
- initialBundleStartLevel = in.readInt();
- nextId = in.readLong();
- }
- } finally {
- in.close();
- }
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Error reading framework metadata: " + e.getMessage()); //$NON-NLS-1$
- Debug.printStackTrace(e);
- }
- }
- }
-
- public AdaptorElementFactory getElementFactory() {
- if (elementFactory == null)
- elementFactory = new EclipseElementFactory();
- return elementFactory;
- }
-
- public void frameworkStart(BundleContext aContext) throws BundleException {
- // EnvironmentInfo has to be initialized first to compute defaults for system context (see bug 88925)
- EclipseEnvironmentInfo.getDefault();
- // must register the xml parser and initialize the plugin converter
- // instance first because we may need it when creating the statemanager
- // in super.frameworkStart(context)
- registerEndorsedXMLParser(aContext);
- PluginConverter converter = new PluginConverterImpl(this, aContext);
- super.frameworkStart(aContext);
- Bundle bundle = aContext.getBundle();
- Location location;
-
- // System property can be set to enable state saver or not.
- if (Boolean.valueOf(FrameworkProperties.getProperty(PROP_ENABLE_STATE_SAVER, "true")).booleanValue()) //$NON-NLS-1$
- stateSaver = new StateSaver();
-
- // Less than optimal reference to EclipseStarter here. Not sure how we
- // can make the location
- // objects available. They are needed very early in EclipseStarter but
- // these references tie the adaptor to that starter.
- location = LocationManager.getUserLocation();
- Hashtable locationProperties = new Hashtable(1);
- if (location != null) {
- locationProperties.put("type", LocationManager.PROP_USER_AREA); //$NON-NLS-1$
- aContext.registerService(Location.class.getName(), location, locationProperties);
- }
- location = LocationManager.getInstanceLocation();
- if (location != null) {
- locationProperties.put("type", LocationManager.PROP_INSTANCE_AREA); //$NON-NLS-1$
- aContext.registerService(Location.class.getName(), location, locationProperties);
- }
- location = LocationManager.getConfigurationLocation();
- if (location != null) {
- locationProperties.put("type", LocationManager.PROP_CONFIG_AREA); //$NON-NLS-1$
- aContext.registerService(Location.class.getName(), location, locationProperties);
- }
- location = LocationManager.getInstallLocation();
- if (location != null) {
- locationProperties.put("type", LocationManager.PROP_INSTALL_AREA); //$NON-NLS-1$
- aContext.registerService(Location.class.getName(), location, locationProperties);
- }
-
- Dictionary urlProperties = new Hashtable();
- urlProperties.put("protocol", new String[] {"bundleentry", "bundleresource"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- aContext.registerService(URLConverter.class.getName(), new URLConverterImpl(), urlProperties);
-
- register(org.eclipse.osgi.service.environment.EnvironmentInfo.class.getName(), EclipseEnvironmentInfo.getDefault(), bundle);
- register(PlatformAdmin.class.getName(), stateManager, bundle);
- register(PluginConverter.class.getName(), converter, bundle);
- register(CommandProvider.class.getName(), new EclipseCommandProvider(aContext), bundle);
- register(FrameworkLog.class.getName(), getFrameworkLog(), bundle);
- registerPerformanceLog(bundle);
- register(org.eclipse.osgi.service.localization.BundleLocalization.class.getName(), new BundleLocalizationImpl(), bundle);
- }
-
- private void registerPerformanceLog(Bundle bundle) {
- Object service = createPerformanceLog();
- String serviceName = FrameworkLog.class.getName();
- Hashtable serviceProperties = new Hashtable(7);
- Dictionary headers = bundle.getHeaders();
-
- serviceProperties.put(Constants.SERVICE_VENDOR, headers.get(Constants.BUNDLE_VENDOR));
- serviceProperties.put(Constants.SERVICE_RANKING, new Integer(Integer.MIN_VALUE));
- serviceProperties.put(Constants.SERVICE_PID, bundle.getBundleId() + '.' + service.getClass().getName());
- serviceProperties.put(FrameworkLog.SERVICE_PERFORMANCE, Boolean.TRUE.toString());
-
- context.registerService(serviceName, service, serviceProperties);
- }
-
- private void setDebugOptions() {
- FrameworkDebugOptions options = FrameworkDebugOptions.getDefault();
- // may be null if debugging is not enabled
- if (options == null)
- return;
- StateManager.DEBUG = options != null;
- StateManager.DEBUG_READER = options.getBooleanOption(OPTION_RESOLVER_READER, false);
- StateManager.MONITOR_PLATFORM_ADMIN = options.getBooleanOption(OPTION_MONITOR_PLATFORM_ADMIN, false);
- StateManager.DEBUG_PLATFORM_ADMIN = options.getBooleanOption(OPTION_PLATFORM_ADMIN, false);
- StateManager.DEBUG_PLATFORM_ADMIN_RESOLVER = options.getBooleanOption(OPTION_PLATFORM_ADMIN_RESOLVER, false);
- PluginConverterImpl.DEBUG = options.getBooleanOption(OPTION_CONVERTER, false);
- BasicLocation.DEBUG = options.getBooleanOption(OPTION_LOCATION, false);
- }
-
- private void registerEndorsedXMLParser(BundleContext bc) {
- try {
- Class.forName(SAXFACTORYNAME);
- bc.registerService(SAXFACTORYNAME, new SaxParsingService(), new Hashtable());
- Class.forName(DOMFACTORYNAME);
- bc.registerService(DOMFACTORYNAME, new DomParsingService(), new Hashtable());
- } catch (ClassNotFoundException e) {
- // In case the JAXP API is not on the boot classpath
- noXML = true;
- if (Debug.DEBUG && Debug.DEBUG_ENABLED) {
- String message = EclipseAdaptorMsg.ECLIPSE_ADAPTOR_ERROR_XML_SERVICE;
- getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, e, null));
- }
- }
- }
-
- private class SaxParsingService implements ServiceFactory {
- public Object getService(Bundle bundle, ServiceRegistration registration) {
- return SAXParserFactory.newInstance();
- }
-
- public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
- // Do nothing.
- }
- }
-
- private class DomParsingService implements ServiceFactory {
- public Object getService(Bundle bundle, ServiceRegistration registration) {
- return DocumentBuilderFactory.newInstance();
- }
-
- public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
- // Do nothing.
- }
- }
-
- public boolean canWrite() {
- return !storageManager.isReadOnly();
- }
-
- public void frameworkStop(BundleContext aContext) throws BundleException {
- saveMetaData();
- super.frameworkStop(aContext);
- printStats();
- if (!noXML)
- PluginParser.releaseXMLParsing();
- storageManager.close();
- }
-
- private void printStats() {
- FrameworkDebugOptions debugOptions = FrameworkDebugOptions.getDefault();
- if (debugOptions == null)
- return;
- String registryParsing = debugOptions.getOption("org.eclipse.core.runtime/registry/parsing/timing/value"); //$NON-NLS-1$
- if (registryParsing != null)
- EclipseAdaptorMsg.debug("Time spent in registry parsing: " + registryParsing); //$NON-NLS-1$
- String packageAdminResolution = debugOptions.getOption("debug.packageadmin/timing/value"); //$NON-NLS-1$
- if (packageAdminResolution != null)
- System.out.println("Time spent in package admin resolve: " + packageAdminResolution); //$NON-NLS-1$
- String constraintResolution = debugOptions.getOption("org.eclipse.core.runtime.adaptor/resolver/timing/value"); //$NON-NLS-1$
- if (constraintResolution != null)
- System.out.println("Time spent resolving the dependency system: " + constraintResolution); //$NON-NLS-1$
- }
-
- private InputStream findBundleDataFile() {
- if (reinitialize)
- return null; // return null to indicate we are reinitializing
- InputStream bundleDataStream = null;
- try {
- bundleDataStream = storageManager.getInputStream(LocationManager.BUNDLE_DATA_FILE);
- } catch (IOException ex) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Error reading framework metadata: " + ex.getMessage()); //$NON-NLS-1$
- Debug.printStackTrace(ex);
- }
- }
- if (bundleDataStream == null) {
- Location currentConfiguration = LocationManager.getConfigurationLocation();
- Location parentConfiguration = null;
- if (currentConfiguration != null && (parentConfiguration = currentConfiguration.getParentLocation()) != null) {
- try {
- File bundledataLocationDir = new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME);
- StorageManager newStorageManager = initStorageManager(bundledataLocationDir, "none", true); //$NON-NLS-1$
- bundleDataStream = newStorageManager.getInputStream(LocationManager.BUNDLE_DATA_FILE);
- newStorageManager.close();
- } catch (MalformedURLException e1) {
- // This will not happen since all the URLs are derived by us
- // and we are GODS!
- } catch (IOException e1) {
- // That's ok we will regenerate the .bundleData
- }
- }
- }
- return bundleDataStream;
- }
-
- /**
- * @see org.eclipse.osgi.framework.adaptor.FrameworkAdaptor#getInstalledBundles()
- */
- public BundleData[] getInstalledBundles() {
- InputStream bundleDataStream = findBundleDataFile();
- if (bundleDataStream == null)
- return null;
-
- try {
- DataInputStream in = new DataInputStream(new BufferedInputStream(bundleDataStream));
- try {
- byte version = in.readByte();
- if (version != BUNDLEDATA_VERSION)
- return null;
- // skip timeStamp - was read by readHeaders
- in.readLong();
- in.readInt();
- in.readLong();
-
- int bundleCount = in.readInt();
- ArrayList result = new ArrayList(bundleCount);
- long id = -1;
- boolean bundleDiscarded = false;
- for (int i = 0; i < bundleCount; i++) {
- try {
- id = in.readLong();
- if (id != 0) {
- EclipseBundleData data = (EclipseBundleData) getElementFactory().createBundleData(this, id);
- loadMetaDataFor(data, in, version);
- data.initializeExistingBundle();
- if (Debug.DEBUG && Debug.DEBUG_GENERAL)
- Debug.println("BundleData created: " + data); //$NON-NLS-1$
- processExtension(data, EXTENSION_INITIALIZE);
- result.add(data);
- }
- } catch (NumberFormatException e) {
- // should never happen
- bundleDiscarded = true;
- } catch (BundleException e) {
- // should never happen
- bundleDiscarded = true;
- } catch (IOException e) {
- bundleDiscarded = true;
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Error reading framework metadata: " + e.getMessage()); //$NON-NLS-1$
- Debug.printStackTrace(e);
- }
- }
- }
- if (bundleDiscarded)
- FrameworkProperties.setProperty(EclipseStarter.PROP_REFRESH_BUNDLES, "true"); //$NON-NLS-1$
- return (BundleData[]) result.toArray(new BundleData[result.size()]);
- } finally {
- in.close();
- }
- } catch (IOException e) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Error reading framework metadata: " + e.getMessage()); //$NON-NLS-1$
- Debug.printStackTrace(e);
- }
- }
- return null;
- }
-
- /**
- * Loads the meta data for the specified bundle data
- * @param data the bundle data to load meta data for
- * @param in the stream to read the meta data from
- * @param version the version of data being read
- * @throws IOException when an io error occurs reading the metadata
- */
- protected void loadMetaDataFor(EclipseBundleData data, DataInputStream in, byte version) throws IOException {
- byte flag = in.readByte();
- if (flag == NULL)
- return;
- data.setLocation(readString(in, false));
- data.setFileName(readString(in, false));
- data.setSymbolicName(readString(in, false));
- data.setVersion(loadVersion(in));
- data.setActivator(readString(in, false));
- data.setAutoStart(in.readBoolean());
- int exceptionsCount = in.readInt();
- String[] autoStartExceptions = exceptionsCount > 0 ? new String[exceptionsCount] : null;
- for (int i = 0; i < exceptionsCount; i++)
- autoStartExceptions[i] = in.readUTF();
- data.setAutoStartExceptions(autoStartExceptions);
- data.hasPackageInfo = in.readBoolean();
- data.buddyList = readString(in, false);
- data.registeredBuddyList = readString(in, false);
- data.setPluginClass(readString(in, false));
- data.setClassPathString(readString(in, false));
- data.setNativePaths(readString(in, false));
- data.setExecutionEnvironment(readString(in, false));
- data.setDynamicImports(readString(in, false));
- data.setGeneration(in.readInt());
- data.setStartLevel(in.readInt());
- data.setStatus(in.readInt());
- data.setReference(in.readBoolean());
- data.setManifestTimeStamp(in.readLong());
- data.setManifestType(in.readByte());
- data.setLastModified(in.readLong());
- data.setType(in.readInt());
- // TODO should we rearrange the isRefernce data before the fileName data?
- // this step is done at the end because the FileName data is read before the isReference data
- if (data.isReference()) {
- // fileName for bundles installed with reference URLs is stored relative to the install location
- File storedPath = new File(data.getFileName());
- if (!storedPath.isAbsolute())
- // make sure it has the absolute location instead
- data.setFileName(new FilePath(installPath + data.getFileName()).toString());
- }
- data.setDirty(false);
- }
-
- private Version loadVersion(DataInputStream in) throws IOException {
- String versionString = readString(in, false);
- try {
- return Version.parseVersion(versionString);
- } catch (IllegalArgumentException e) {
- return new InvalidVersion(versionString);
- }
- }
-
- /**
- * Saves the metadata for the specified bundle data. This method only marks the bundle data
- * as dirty if the bundle is not auto started. The bundle data is not persisted until the
- * framework is shutdown.
- * @param data
- * @throws IOException
- */
- public void saveMetaDataFor(EclipseBundleData data) throws IOException {
- if (data.isDirty()) {
- timeStamp--; // Change the value of the timeStamp, as a marker that something changed.
- requestSave();
- }
- }
-
- public void setInitialBundleStartLevel(int value) {
- super.setInitialBundleStartLevel(value);
- // Change the value of the timeStamp, as a marker that something changed.
- timeStamp--;
- requestSave();
- }
-
- public void persistNextBundleID(long value) {
- // Do nothing the timeStamp will have changed because the state will be
- // updated.
- }
-
- /**
- * Saves the metadata for the specified bundle data.
- * @param data the bundle data
- * @param out the stream to save the metadata to
- * @throws IOException when an io error occurs saving the metadata
- */
- protected void saveMetaDataFor(BundleData data, DataOutputStream out) throws IOException {
- if (data.getBundleID() == 0 || !(data instanceof AbstractBundleData)) {
- out.writeByte(NULL);
- return;
- }
- EclipseBundleData bundleData = (EclipseBundleData) data;
- out.writeByte(OBJECT);
- writeStringOrNull(out, bundleData.getLocation());
- String storedFileName = bundleData.isReference() ? new FilePath(installPath).makeRelative(new FilePath(bundleData.getFileName())) : bundleData.getFileName();
- writeStringOrNull(out, storedFileName);
- writeStringOrNull(out, bundleData.getSymbolicName());
- writeStringOrNull(out, bundleData.getVersion().toString());
- writeStringOrNull(out, bundleData.getActivator());
- out.writeBoolean(bundleData.isAutoStart());
- String[] autoStartExceptions = bundleData.getAutoStartExceptions();
- if (autoStartExceptions == null)
- out.writeInt(0);
- else {
- out.writeInt(autoStartExceptions.length);
- for (int i = 0; i < autoStartExceptions.length; i++)
- out.writeUTF(autoStartExceptions[i]);
- }
- out.writeBoolean(bundleData.hasPackageInfo);
- writeStringOrNull(out, bundleData.buddyList);
- writeStringOrNull(out, bundleData.registeredBuddyList);
- writeStringOrNull(out, bundleData.getPluginClass());
- writeStringOrNull(out, bundleData.getClassPathString());
- writeStringOrNull(out, bundleData.getNativePathsString());
- writeStringOrNull(out, bundleData.getExecutionEnvironment());
- writeStringOrNull(out, bundleData.getDynamicImports());
- out.writeInt(bundleData.getGeneration());
- out.writeInt(bundleData.getStartLevel());
- out.writeInt(bundleData.getPersistentStatus());
- out.writeBoolean(bundleData.isReference());
- out.writeLong(bundleData.getManifestTimeStamp());
- out.writeByte(bundleData.getManifestType());
- out.writeLong(bundleData.getLastModified());
- out.writeInt(bundleData.getType());
- }
-
- private String readString(DataInputStream in, boolean intern) throws IOException {
- byte type = in.readByte();
- if (type == NULL)
- return null;
- return intern ? in.readUTF().intern() : in.readUTF();
- }
-
- private void writeStringOrNull(DataOutputStream out, String string) throws IOException {
- if (string == null)
- out.writeByte(NULL);
- else {
- out.writeByte(OBJECT);
- out.writeUTF(string);
- }
- }
-
- /**
- * Persists the bundle data for all bundles installed in the framework.
- */
- public void saveMetaData() {
- // the cache and the state match
- if (!canWrite() | timeStamp == stateManager.getSystemState().getTimeStamp())
- return;
- try {
- ManagedOutputStream fmos = storageManager.getOutputStream(LocationManager.BUNDLE_DATA_FILE);
- DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fmos));
- boolean error = true;
- try {
- out.writeByte(BUNDLEDATA_VERSION);
- out.writeLong(stateManager.getSystemState().getTimeStamp());
- out.writeInt(initialBundleStartLevel);
- out.writeLong(nextId);
- Bundle[] bundles = context.getBundles();
- out.writeInt(bundles.length);
- for (int i = 0; i < bundles.length; i++) {
- long id = bundles[i].getBundleId();
- out.writeLong(id);
- if (id != 0) {
- BundleData data = ((org.eclipse.osgi.framework.internal.core.AbstractBundle) bundles[i]).getBundleData();
- saveMetaDataFor(data, out);
- }
- }
- out.close();
- // update the 'timeStamp' after the changed Meta data is saved.
- timeStamp = stateManager.getSystemState().getTimeStamp();
- error = false;
- } finally {
- // if something happens, don't close a corrupt file
- if (error) {
- fmos.abort();
- try {
- out.close();
- } catch (IOException e) {/*ignore*/
- }
- }
- }
- } catch (IOException e) {
- frameworkLog.log(new FrameworkEvent(FrameworkEvent.ERROR, context.getBundle(), e));
- return;
- }
- }
-
- public BundleWatcher getBundleWatcher() {
- return StatsManager.getDefault();
- }
-
- /**
- * Returns the system bundle context
- * @return the system bundle context
- */
- protected BundleContext getContext() {
- return context;
- }
-
- public void frameworkStopping(BundleContext aContext) {
- super.frameworkStopping(aContext);
- // Shutdown the ApplicationLauncher service if it is available.
- ServiceReference launcherRef = aContext.getServiceReference(ApplicationLauncher.class.getName());
- if (launcherRef != null) {
- ApplicationLauncher launcher = (ApplicationLauncher) aContext.getService(launcherRef);
- // this will force a currently running application to stop.
- launcher.shutdown();
- aContext.ungetService(launcherRef);
- }
- stopper = new BundleStopper(context);
- stopper.stopBundles();
- }
-
- private boolean isFatalException(Throwable error) {
- if (error instanceof VirtualMachineError) {
- return true;
- }
- if (error instanceof ThreadDeath) {
- return true;
- }
- return false;
- }
-
- public void handleRuntimeError(Throwable error) {
- try {
- // check the prop each time this happens (should NEVER happen!)
- exitOnError = Boolean.valueOf(FrameworkProperties.getProperty(PROP_EXITONERROR, "true")).booleanValue(); //$NON-NLS-1$
- String message = EclipseAdaptorMsg.ECLIPSE_ADAPTOR_RUNTIME_ERROR;
- if (exitOnError && isFatalException(error))
- message += ' ' + EclipseAdaptorMsg.ECLIPSE_ADAPTOR_EXITING;
- FrameworkLogEntry logEntry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, error, null);
- getFrameworkLog().log(logEntry);
- } catch (Throwable t) {
- // we may be in a currupted state and must be able to handle any
- // errors (ie OutOfMemoryError)
- // that may occur when handling the first error; this is REALLY the
- // last resort.
- try {
- error.printStackTrace();
- t.printStackTrace();
- } catch (Throwable t1) {
- // if we fail that then we are beyond help.
- }
- } finally {
- // do the exit outside the try block just incase another runtime
- // error was thrown while logging
- if (exitOnError && isFatalException(error))
- System.exit(13);
- }
- }
-
- protected void setLog(FrameworkLog log) {
- frameworkLog = log;
- }
-
- BundleStopper getBundleStopper() {
- return stopper;
- }
-
- private StorageManager initStorageManager(File baseDir, String lockMode, boolean readOnly) {
- StorageManager manager = new StorageManager(baseDir, lockMode, readOnly);
- try {
- manager.open(!readOnly);
- } catch (IOException ex) {
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Error reading framework metadata: " + ex.getMessage()); //$NON-NLS-1$
- Debug.printStackTrace(ex);
- }
- String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_FILEMANAGER_OPEN_ERROR, ex.getMessage());
- FrameworkLogEntry logEntry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, ex, null);
- getFrameworkLog().log(logEntry);
- }
- return manager;
- }
-
- protected void updateState(BundleData bundleData, int type) throws BundleException {
- super.updateState(bundleData, type);
- requestSave();
- }
-
- private void requestSave() {
- // Only when the State saver is enabled will the stateSaver be started.
- if (stateSaver == null)
- return;
- if (stateManager != null)
- stateSaver.requestSave();
- }
-
- private class StateSaver implements Runnable {
- private long delay_interval = 30000; // 30 seconds.
- private long max_total_delay_interval = 1800000; // 30 minutes.
- private boolean shutdown = false;
- private long lastSaveTime = 0;
- private Thread runningThread = null;
-
- StateSaver() {
- String prop = FrameworkProperties.getProperty("eclipse.stateSaveDelayInterval"); //$NON-NLS-1$
- if (prop != null) {
- try {
- long val = Long.parseLong(prop);
- if (val >= 1000 && val <= 1800000) {
- delay_interval = val;
- max_total_delay_interval = val * 60;
- }
- } catch (NumberFormatException e) {
- // ignore
- }
- }
- }
-
- public void run() {
- State systemState = getState();
- synchronized (systemState) {
- long firstSaveTime = lastSaveTime;
- long curSaveTime = 0;
- long delayTime;
- do {
- do {
- if ((System.currentTimeMillis() - firstSaveTime) > max_total_delay_interval)
- // Waiting time has been too long, so break to start saving State data to file.
- break;
- delayTime = Math.min(delay_interval, lastSaveTime - curSaveTime);
- curSaveTime = lastSaveTime;
- // wait for other save requests
- try {
- if (!shutdown)
- systemState.wait(delayTime);
- } catch (InterruptedException ie) {
- // force break from do/while loops
- curSaveTime = lastSaveTime;
- break;
- }
-
- // Continue the loop if 'lastSaveTime' is increased again during waiting.
- } while (!shutdown && curSaveTime < lastSaveTime);
- // Save State and Meta data.
- saveStateToFile(false);
- saveMetaData();
- // Continue the loop if Saver is asked again during saving State data to file.
- } while (!shutdown && curSaveTime < lastSaveTime);
- runningThread = null; // clear runningThread
- }
- }
-
- void shutdown() {
- State systemState = getState();
- Thread joinWith = null;
- synchronized (systemState) {
- shutdown = true;
- joinWith = runningThread;
- systemState.notifyAll(); // To wakeup sleeping thread.
- }
- try {
- if (joinWith != null)
- // There should be no deadlock when 'shutdown' is true.
- joinWith.join();
- } catch (InterruptedException ie){
- if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
- Debug.println("Error shutdowning StateSaver: " + ie.getMessage()); //$NON-NLS-1$
- Debug.printStackTrace(ie);
- }
- }
- }
-
- void requestSave() {
- State systemState = getState();
- synchronized (systemState) {
- lastSaveTime = System.currentTimeMillis();
- if (runningThread == null) {
- runningThread = new Thread(this, "State Saver"); //$NON-NLS-1$
- runningThread.start();
- }
- }
- }
- }
-}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseBundleData.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseBundleData.java
deleted file mode 100644
index dd797787a..000000000
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseBundleData.java
+++ /dev/null
@@ -1,575 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2006 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.core.runtime.adaptor;
-
-import java.io.*;
-import java.net.URL;
-import java.util.*;
-import org.eclipse.core.runtime.internal.adaptor.*;
-import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
-import org.eclipse.osgi.framework.adaptor.core.*;
-import org.eclipse.osgi.framework.internal.core.Constants;
-import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
-import org.eclipse.osgi.framework.log.FrameworkLogEntry;
-import org.eclipse.osgi.framework.util.Headers;
-import org.eclipse.osgi.service.datalocation.Location;
-import org.eclipse.osgi.service.pluginconversion.PluginConversionException;
-import org.eclipse.osgi.util.ManifestElement;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Version;
-
-/**
- * The BundleData implementation used Eclipse.
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.1
- */
-//Maybe for consistency should it be overriden to do nothing. See also EclipseAdaptor.saveMetadataFor(BundleData)
-public class EclipseBundleData extends AbstractBundleData {
- /** bundle manifest type unknown */
- static public final byte MANIFEST_TYPE_UNKNOWN = PluginConverterImpl.MANIFEST_TYPE_UNKNOWN;
- /** bundle manifest type bundle (META-INF/MANIFEST.MF) */
- static public final byte MANIFEST_TYPE_BUNDLE = PluginConverterImpl.MANIFEST_TYPE_BUNDLE;
- /** bundle manifest type plugin (plugin.xml) */
- static public final byte MANIFEST_TYPE_PLUGIN = PluginConverterImpl.MANIFEST_TYPE_PLUGIN;
- /** bundle manifest type fragment (fragment.xml) */
- static public final byte MANIFEST_TYPE_FRAGMENT = PluginConverterImpl.MANIFEST_TYPE_FRAGMENT;
- /** bundle manifest type jared bundle */
- static public final byte MANIFEST_TYPE_JAR = PluginConverterImpl.MANIFEST_TYPE_JAR;
-
- private static String[] libraryVariants = null;
-
- /** data to detect modification made in the manifest */
- private long manifestTimeStamp = 0;
- private byte manifestType = MANIFEST_TYPE_UNKNOWN;
-
- // URL protocol designations
- /** The platform protocol */
- public static final String PROTOCOL = "platform"; //$NON-NLS-1$
- /** The file protocol */
- public static final String FILE = "file"; //$NON-NLS-1$
-
- private static final String PROP_CHECK_CONFIG = "osgi.checkConfiguration"; //$NON-NLS-1$
- /** the Plugin-Class header */
- protected String pluginClass = null;
- /** Eclipse-AutoStart header */
- private boolean autoStart;
- private String[] autoStartExceptions;
- /** shortcut to know if a bundle has a buddy */
- protected String buddyList;
- /** shortcut to know if a bundle is a registrant to a registered policy */
- protected String registeredBuddyList;
- /** shortcut to know if the bundle manifest has package info */
- protected boolean hasPackageInfo;
- /** marks the data as dirty */
- protected boolean dirty = false;
-
- private static String[] buildLibraryVariants() {
- ArrayList result = new ArrayList();
- EclipseEnvironmentInfo info = EclipseEnvironmentInfo.getDefault();
- result.add("ws/" + info.getWS() + "/"); //$NON-NLS-1$ //$NON-NLS-2$
- result.add("os/" + info.getOS() + "/" + info.getOSArch() + "/"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- result.add("os/" + info.getOS() + "/"); //$NON-NLS-1$ //$NON-NLS-2$
- String nl = info.getNL();
- nl = nl.replace('_', '/');
- while (nl.length() > 0) {
- result.add("nl/" + nl + "/"); //$NON-NLS-1$ //$NON-NLS-2$
- int i = nl.lastIndexOf('/');
- nl = (i < 0) ? "" : nl.substring(0, i); //$NON-NLS-1$
- }
- result.add(""); //$NON-NLS-1$
- return (String[]) result.toArray(new String[result.size()]);
- }
-
- /**
- * Constructor for EclipseBundleData.
- * @param adaptor The adaptor for this bundle data
- * @param id The bundle id for this bundle data
- */
- public EclipseBundleData(AbstractFrameworkAdaptor adaptor, long id) {
- super(adaptor, id);
- }
-
- /**
- * Initialize an existing bundle
- * @throws IOException if any error occurs loading the existing bundle
- */
- public void initializeExistingBundle() throws IOException {
- createBaseBundleFile();
- if (!checkManifestTimeStamp()) {
- if (getBundleStoreDir().exists()) {
- /* create .delete */
- FileOutputStream out = new FileOutputStream(new File(getBundleStoreDir(), ".delete"));
- out.close();
- }
- throw new IOException();
- }
- }
-
- private boolean checkManifestTimeStamp() {
- if (!"true".equalsIgnoreCase(FrameworkProperties.getProperty(PROP_CHECK_CONFIG))) //$NON-NLS-1$
- return true;
-
- if (PluginConverterImpl.getTimeStamp(getBaseFile(), getManifestType()) == getManifestTimeStamp()) {
- if ((getManifestType() & (MANIFEST_TYPE_JAR | MANIFEST_TYPE_BUNDLE)) != 0)
- return true;
- String cacheLocation = FrameworkProperties.getProperty(LocationManager.PROP_MANIFEST_CACHE);
- Location parentConfiguration = LocationManager.getConfigurationLocation().getParentLocation();
- if (parentConfiguration != null) {
- try {
- return checkManifestAndParent(cacheLocation, getSymbolicName(), getVersion().toString(), getManifestType()) != null;
- } catch (BundleException e) {
- return false;
- }
- }
- File cacheFile = new File(cacheLocation, getSymbolicName() + '_' + getVersion() + ".MF"); //$NON-NLS-1$
- if (cacheFile.isFile())
- return true;
- }
- return false;
- }
-
- /**
- * Returns the absolute path name of a native library. The VM invokes this
- * method to locate the native libraries that belong to classes loaded with
- * this class loader. If this method returns <code>null</code>, the VM
- * searches the library along the path specified as the <code>java.library.path</code>
- * property.
- *
- * @param libName
- * the library name
- * @return the absolute path of the native library
- */
- public String findLibrary(String libName) {
- // first do the standard OSGi lookup using the native clauses
- // in the manifest. If that fails, do the legacy Eclipse lookup.
- String result = super.findLibrary(libName);
- if (result != null)
- return result;
- if (libraryVariants == null)
- libraryVariants = buildLibraryVariants();
- if (libName.length() == 0)
- return null;
- if (libName.charAt(0) == '/' || libName.charAt(0) == '\\')
- libName = libName.substring(1);
- libName = System.mapLibraryName(libName);
-
- // if (DEBUG && DEBUG_SHOW_ACTIONS && debugNative(libName))
- // debug("findLibrary(" + libName + ")"); //$NON-NLS-1$ //$NON-NLS-2$
-
- return searchVariants(libraryVariants, libName);
-
- }
-
- private String searchVariants(String[] variants, String path) {
- for (int i = 0; i < variants.length; i++) {
- BundleEntry libEntry = baseBundleFile.getEntry(variants[i] + path);
- if (libEntry == null) {
- // if (DEBUG && DEBUG_SHOW_FAILURE)
- // debug("not found " + variants[i] + path);
- // //$NON-NLS-1$
- } else {
- // if (DEBUG && DEBUG_SHOW_SUCCESS)
- // debug("found " + path + " as " +
- // variants[i] + path); //$NON-NLS-1$ //$NON-NLS-2$
- File libFile = baseBundleFile.getFile(variants[i] + path);
- if (libFile == null)
- return null;
- // see bug 88697 - HP requires libraries to have executable permissions
- if (org.eclipse.osgi.service.environment.Constants.OS_HPUX.equals(EclipseEnvironmentInfo.getDefault().getOS())) {
- try {
- // use the string array method in case there is a space in the path
- Runtime.getRuntime().exec(new String[] {"chmod", "755", libFile.getAbsolutePath()}).waitFor(); //$NON-NLS-1$ //$NON-NLS-2$
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- return libFile.getAbsolutePath();
- }
- }
- return null;
- }
-
- //TODO Unused method
- private URL[] getSearchURLs(URL target) {
- return new URL[] {target};
- }
-
- public synchronized Dictionary getManifest() throws BundleException {
- return getManifest(false);
- }
-
- /**
- * Gets the manifest for this bundle. If this is the first time the manifest is
- * ever accessed then the manifest is loaded from the manifest file in the bundle;
- * otherwise the manifest is loaded from cached data.
- * @param first set to true if this is the first time the manifest is accessed
- * for this bundle
- * @return the manifest for this bundle
- * @throws BundleException if any error occurs loading the manifest
- */
- public synchronized Dictionary getManifest(boolean first) throws BundleException {
- if (manifest == null)
- manifest = first ? loadManifest() : new CachedManifest(this);
- return manifest;
- }
-
- private boolean isComplete(Dictionary manifest) {
- // a manifest is complete if it has a Bundle-SymbolicName entry...
- if (manifest.get(org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME) != null)
- return true;
- // ...or it does not have a plugin/fragment manifest where to get the other entries from
- return getEntry(PluginConverterImpl.PLUGIN_MANIFEST) == null && getEntry(PluginConverterImpl.FRAGMENT_MANIFEST) == null;
- }
-
- /**
- * Loads the bundle manifest from the bundle.
- * @return the bundle manifest
- * @throws BundleException if an error occurs loading the bundle manifest
- */
- public synchronized Dictionary loadManifest() throws BundleException {
- URL url = getEntry(Constants.OSGI_BUNDLE_MANIFEST);
- if (url != null) {
- // the bundle has a built-in manifest - we may not have to generate one
- Dictionary builtIn = loadManifestFrom(url);
- // if the manifest is not complete, add entries derived from plug-in/fragment manifest
- if (!isComplete(builtIn)) {
- Dictionary generatedManifest = generateManifest(builtIn);
- if (generatedManifest != null)
- return generatedManifest;
- }
- // the manifest is complete or we could not complete it - take it as it is
- manifestType = MANIFEST_TYPE_BUNDLE;
- if (getBaseFile().isFile()) {
- manifestTimeStamp = getBaseFile().lastModified();
- manifestType |= MANIFEST_TYPE_JAR;
- } else
- manifestTimeStamp = getBaseBundleFile().getEntry(Constants.OSGI_BUNDLE_MANIFEST).getTime();
- return builtIn;
- }
- Dictionary result = generateManifest(null);
- if (result == null)
- throw new BundleException(NLS.bind(EclipseAdaptorMsg.ECLIPSE_DATA_MANIFEST_NOT_FOUND, getLocation()));
- return result;
- }
-
- private Headers basicCheckManifest(String cacheLocation, String symbolicName, String version, byte inputType) throws BundleException {
- File currentFile = new File(cacheLocation, symbolicName + '_' + version + ".MF"); //$NON-NLS-1$
- if (PluginConverterImpl.upToDate(currentFile, getBaseFile(), inputType)) {
- try {
- return Headers.parseManifest(new FileInputStream(currentFile));
- } catch (FileNotFoundException e) {
- // do nothing.
- }
- }
- return null;
- }
-
- private Headers checkManifestAndParent(String cacheLocation, String symbolicName, String version, byte inputType) throws BundleException {
- Headers result = basicCheckManifest(cacheLocation, symbolicName, version, inputType);
- if (result != null)
- return result;
-
- Location parentConfiguration = null;
- if ((parentConfiguration = LocationManager.getConfigurationLocation().getParentLocation()) != null) {
- result = basicCheckManifest(new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + '/' + LocationManager.MANIFESTS_DIR).toString(), symbolicName, version, inputType);
- }
- return result;
- }
-
- private Dictionary generateManifest(Dictionary originalManifest) throws BundleException {
- String cacheLocation = FrameworkProperties.getProperty(LocationManager.PROP_MANIFEST_CACHE);
- if (getSymbolicName() != null) {
- Headers existingHeaders = checkManifestAndParent(cacheLocation, getSymbolicName(), getVersion().toString(), manifestType);
- if (existingHeaders != null)
- return existingHeaders;
- }
-
- PluginConverterImpl converter = PluginConverterImpl.getDefault();
-
- Dictionary generatedManifest;
- try {
- generatedManifest = converter.convertManifest(getBaseFile(), true, null, true, null);
- } catch (PluginConversionException pce) {
- String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_ERROR_CONVERTING, getBaseFile());
- throw new BundleException(message, pce);
- }
-
- //Now we know the symbolicId and the version of the bundle, we check to see if don't have a manifest for it already
- Version version = Version.parseVersion((String) generatedManifest.get(Constants.BUNDLE_VERSION));
- String symbolicName = ManifestElement.parseHeader(org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME, (String) generatedManifest.get(org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME))[0].getValue();
- ManifestElement generatedFrom = ManifestElement.parseHeader(PluginConverterImpl.GENERATED_FROM, (String) generatedManifest.get(PluginConverterImpl.GENERATED_FROM))[0];
- Headers existingHeaders = checkManifestAndParent(cacheLocation, symbolicName, version.toString(), Byte.parseByte(generatedFrom.getAttribute(PluginConverterImpl.MANIFEST_TYPE_ATTRIBUTE)));
- //We don't have a manifest.
- setManifestTimeStamp(Long.parseLong(generatedFrom.getValue()));
- setManifestType(Byte.parseByte(generatedFrom.getAttribute(PluginConverterImpl.MANIFEST_TYPE_ATTRIBUTE)));
- if (!adaptor.canWrite() || existingHeaders != null)
- return existingHeaders;
-
- //merge the original manifest with the generated one
- if (originalManifest != null) {
- Enumeration keysEnum = originalManifest.keys();
- while (keysEnum.hasMoreElements()) {
- Object key = keysEnum.nextElement();
- generatedManifest.put(key, originalManifest.get(key));
- }
- }
-
- //write the generated manifest
- File bundleManifestLocation = new File(cacheLocation, symbolicName + '_' + version.toString() + ".MF"); //$NON-NLS-1$
- try {
- converter.writeManifest(bundleManifestLocation, generatedManifest, true);
- } catch (Exception e) {
- //TODO Need to log
- }
- return generatedManifest;
-
- }
-
- private Dictionary loadManifestFrom(URL manifestURL) throws BundleException {
- try {
- return Headers.parseManifest(manifestURL.openStream());
- } catch (IOException e) {
- throw new BundleException(NLS.bind(EclipseAdaptorMsg.ECLIPSE_DATA_ERROR_READING_MANIFEST, getLocation()), e);
- }
- }
-
- protected void loadFromManifest() throws BundleException {
- getManifest(true);
- super.loadFromManifest();
- // manifest cannot ever be a cached one otherwise the lines below are bogus
- if (manifest instanceof CachedManifest)
- throw new IllegalStateException();
- pluginClass = (String) manifest.get(EclipseAdaptor.PLUGIN_CLASS);
- String lazyStart = (String) manifest.get(EclipseAdaptor.ECLIPSE_LAZYSTART);
- if (lazyStart == null)
- lazyStart = (String) manifest.get(EclipseAdaptor.ECLIPSE_AUTOSTART);
- parseAutoStart(lazyStart);
- buddyList = (String) manifest.get(Constants.BUDDY_LOADER);
- registeredBuddyList = (String) manifest.get(Constants.REGISTERED_POLICY);
- hasPackageInfo = hasPackageInfo(getEntry(Constants.OSGI_BUNDLE_MANIFEST));
- }
-
- // Used to check the bundle manifest file for any package information.
- // This is used when '.' is on the Bundle-ClassPath to prevent reading
- // the bundle manifest for pacakge information when loading classes.
- private boolean hasPackageInfo(URL url) {
- if (url == null)
- return false;
- BufferedReader br = null;
- try {
- br = new BufferedReader(new InputStreamReader(url.openStream()));
- String line;
- while ((line = br.readLine()) != null) {
- if (line.startsWith("Specification-Title: ") || line.startsWith("Specification-Version: ") || line.startsWith("Specification-Vendor: ") || line.startsWith("Implementation-Title: ") || line.startsWith("Implementation-Version: ") || line.startsWith("Implementation-Vendor: ")) //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
- return true;
- }
- } catch (IOException ioe) {
- // do nothing
- } finally {
- if (br != null)
- try {
- br.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- return false;
- }
-
- /**
- * Returns the plugin class
- * @return the plugin class
- */
- public String getPluginClass() {
- return pluginClass;
- }
-
- /**
- * Returns the buddy list for this bundle
- * @return the buddy list for this bundle
- */
- public String getBuddyList() {
- return buddyList;
- }
-
- /**
- * Returns the registered buddy list for this bundle
- * @return the registered buddy list for this bundle
- */
- public String getRegisteredBuddyList() {
- return registeredBuddyList;
- }
-
- /**
- * Sets the plugin class
- * @param value the plugin class
- */
- public void setPluginClass(String value) {
- pluginClass = value;
- }
-
- /**
- * Returns the timestamp for the manifest file
- * @return the timestamp for the manifest file
- */
- public long getManifestTimeStamp() {
- return manifestTimeStamp;
- }
-
- /**
- * Sets the manifest timestamp for this bundle
- * @param stamp the manifest timestamp
- */
- public void setManifestTimeStamp(long stamp) {
- manifestTimeStamp = stamp;
- }
-
- /**
- * Returns the manifest type
- * @return the manifest type
- */
- public byte getManifestType() {
- return manifestType;
- }
-
- /**
- * Sets the manifest type
- * @param manifestType the manifest type
- */
- public void setManifestType(byte manifestType) {
- this.manifestType = manifestType;
- }
-
- /**
- * Sets the auto start flag
- * @param value the auto start flag
- */
- public void setAutoStart(boolean value) {
- autoStart = value;
- }
-
- /**
- * Checks whether this bundle is auto started for all resource/class loads
- * @return true if the bundle is auto started; false otherwise
- */
- public boolean isAutoStart() {
- return autoStart;
- }
-
- /**
- * Returns the status of this bundle which is persisted on shutdown. For bundles
- * which are auto started the started state is removed to prevent the bundle from
- * being started on the next startup.
- * @return the status of this bundle which is persisted on shutdown
- */
- public int getPersistentStatus() {
- // omit the active state if necessary
- return isAutoStartable() ? (~Constants.BUNDLE_STARTED) & getStatus() : getStatus();
- }
-
- /**
- * Sets the list of auto start exceptions for this bundle
- * @param autoStartExceptions the list of auto start exceptions
- */
- public void setAutoStartExceptions(String[] autoStartExceptions) {
- this.autoStartExceptions = autoStartExceptions;
- }
-
- /**
- * Returns the auto start exception packages
- * @return the auto start exception packages
- */
- public String[] getAutoStartExceptions() {
- return autoStartExceptions;
- }
-
- private void parseAutoStart(String headerValue) {
- autoStart = false;
- autoStartExceptions = null;
- ManifestElement[] allElements = null;
- try {
- allElements = ManifestElement.parseHeader(EclipseAdaptor.ECLIPSE_LAZYSTART, headerValue);
- } catch (BundleException e) {
- // just use the default settings (no auto activation)
- String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_CANNOT_GET_HEADERS, getLocation());
- EclipseAdaptor.getDefault().getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, e, null));
- }
- //Eclipse-AutoStart not found...
- if (allElements == null)
- return;
- // the single value for this element should be true|false
- autoStart = "true".equalsIgnoreCase(allElements[0].getValue()); //$NON-NLS-1$
- // look for any exceptions (the attribute) to the autoActivate setting
- String exceptionsValue = allElements[0].getAttribute(EclipseAdaptor.ECLIPSE_LAZYSTART_EXCEPTIONS);
- if (exceptionsValue == null)
- return;
- StringTokenizer tokenizer = new StringTokenizer(exceptionsValue, ","); //$NON-NLS-1$
- int numberOfTokens = tokenizer.countTokens();
- autoStartExceptions = new String[numberOfTokens];
- for (int i = 0; i < numberOfTokens; i++)
- autoStartExceptions[i] = tokenizer.nextToken().trim();
- }
-
- /**
- * Checks whether this bundle is auto started for all resource/class loads or only for a
- * subset of resource/classloads
- * @return true if the bundle is auto started; false otherwise
- */
- public boolean isAutoStartable() {
- return autoStart || (autoStartExceptions != null && autoStartExceptions.length > 0);
- }
-
- /**
- * Save the bundle data in the data file.
- *
- * @throws IOException if a write error occurs.
- */
- public synchronized void save() throws IOException {
- if (adaptor.canWrite() && isDirty()) {
- ((EclipseAdaptor) adaptor).saveMetaDataFor(this);
- this.dirty = false;
- }
- }
-
- public String toString() {
- return "BundleData for " + getSymbolicName() + " (" + id + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- }
-
- public File getParentGenerationDir() {
- Location parentConfiguration = null;
- Location currentConfiguration = LocationManager.getConfigurationLocation();
- if (currentConfiguration != null && (parentConfiguration = currentConfiguration.getParentLocation()) != null)
- return new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + '/' + LocationManager.BUNDLES_DIR + '/' + getBundleID() + '/' + getGeneration());
- return null;
- }
-
- public void setStartLevel(int startLevel) {
- super.setStartLevel(startLevel);
- dirty = true;
- }
-
- public void setStatus(int status) {
- super.setStatus(status);
- if (!isAutoStartable())
- dirty = true;
- }
-
- public boolean isDirty() {
- return dirty;
- }
-
- void setDirty (boolean dirty) {
- this.dirty = dirty;
- }
-}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseClassLoader.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseClassLoader.java
deleted file mode 100644
index 07f120434..000000000
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseClassLoader.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2006 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.core.runtime.adaptor;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.security.ProtectionDomain;
-import java.util.ArrayList;
-import java.util.StringTokenizer;
-import java.util.jar.Attributes;
-import java.util.jar.Manifest;
-import org.eclipse.core.runtime.internal.adaptor.BundleStopper;
-import org.eclipse.core.runtime.internal.adaptor.EclipseEnvironmentInfo;
-import org.eclipse.core.runtime.internal.stats.*;
-import org.eclipse.osgi.framework.adaptor.*;
-import org.eclipse.osgi.framework.adaptor.core.*;
-import org.eclipse.osgi.framework.internal.core.AbstractBundle;
-import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
-import org.eclipse.osgi.framework.internal.core.Msg;
-import org.eclipse.osgi.framework.log.FrameworkLogEntry;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.*;
-
-/**
- * Implements the class loader for Eclipse
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.1
- */
-public class EclipseClassLoader extends DefaultClassLoader {
- private static String[] NL_JAR_VARIANTS = buildNLJarVariants(EclipseEnvironmentInfo.getDefault().getNL());
- private static boolean DEFINE_PACKAGES;
- private static final String VARIABLE_DELIM_STRING = "$"; //$NON-NLS-1$
- private static final char VARIABLE_DELIM_CHAR = '$';
- private static final String EXTERNAL_LIB_PREFIX = "external:"; //$NON-NLS-1$
- static {
- try {
- Class.forName("java.lang.Package"); //$NON-NLS-1$
- DEFINE_PACKAGES = true;
- } catch (ClassNotFoundException e) {
- DEFINE_PACKAGES = false;
- }
- }
-
- public EclipseClassLoader(ClassLoaderDelegate delegate, ProtectionDomain domain, String[] classpath, ClassLoader parent, BundleData bundleData) {
- super(delegate, domain, classpath, parent, (EclipseBundleData) bundleData);
- }
-
- public Class findLocalClass(String className) throws ClassNotFoundException {
- if (StatsManager.MONITOR_CLASSES) //Suport for performance analysis
- ClassloaderStats.startLoadingClass(getClassloaderId(), className);
- boolean found = true;
-
- try {
- AbstractBundle bundle = (AbstractBundle) hostdata.getBundle();
- // If the bundle is active, uninstalled or stopping then the bundle has already
- // been initialized (though it may have been destroyed) so just return the class.
- if ((bundle.getState() & (Bundle.ACTIVE | Bundle.UNINSTALLED | Bundle.STOPPING)) != 0)
- return basicFindLocalClass(className);
-
- // The bundle is not active and does not require activation, just return the class
- if (!shouldActivateFor(className))
- return basicFindLocalClass(className);
-
- // The bundle is starting. Note that if the state changed between the tests
- // above and this test (e.g., it was not ACTIVE but now is), that's ok, we will
- // just try to start it again (else case).
- // TODO need an explanation here of why we duplicated the mechanism
- // from the framework rather than just calling start() and letting it sort it out.
- if (bundle.getState() == Bundle.STARTING) {
- // If the thread trying to load the class is the one trying to activate the bundle, then return the class
- if (bundle.testStateChanging(Thread.currentThread()) || bundle.testStateChanging(null))
- return basicFindLocalClass(className);
-
- // If it's another thread, we wait and try again. In any case the class is returned.
- // The difference is that an exception can be logged.
- // TODO do we really need this test? We just did it on the previous line?
- if (!bundle.testStateChanging(Thread.currentThread())) {
- Thread threadChangingState = bundle.getStateChanging();
- if (StatsManager.TRACE_BUNDLES && threadChangingState != null) {
- System.out.println("Concurrent startup of bundle " + bundle.getSymbolicName() + " by " + Thread.currentThread() + " and " + threadChangingState.getName() + ". Waiting up to 5000ms for " + threadChangingState + " to finish the initialization."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
- }
- long start = System.currentTimeMillis();
- long delay = 5000;
- long timeLeft = delay;
- while (true) {
- try {
- Thread.sleep(100); // do not release the classloader lock (bug 86713)
- if (bundle.testStateChanging(null) || timeLeft <= 0)
- break;
- } catch (InterruptedException e) {
- //Ignore and keep waiting
- }
- timeLeft = start + delay - System.currentTimeMillis();
- }
- if (timeLeft <= 0 || bundle.getState() != Bundle.ACTIVE) {
- String bundleName = bundle.getSymbolicName() == null ? Long.toString(bundle.getBundleId()) : bundle.getSymbolicName();
- String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_CONCURRENT_STARTUP, new Object[] {Thread.currentThread().getName(), className, threadChangingState.getName(), bundleName, Long.toString(delay)});
- EclipseAdaptor.getDefault().getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, new Exception(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_GENERATED_EXCEPTION), null));
- }
- return basicFindLocalClass(className);
- }
- }
-
- //The bundle must be started.
- try {
- hostdata.getBundle().start();
- } catch (BundleException e) {
- String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_ACTIVATION, bundle.getSymbolicName(), Long.toString(bundle.getBundleId()));
- EclipseAdaptor.getDefault().getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, e, null));
- throw new ClassNotFoundException(className, e);
- }
- return basicFindLocalClass(className);
- } catch (ClassNotFoundException e) {
- found = false;
- throw e;
- } finally {
- if (StatsManager.MONITOR_CLASSES)
- ClassloaderStats.endLoadingClass(getClassloaderId(), className, found);
- }
- }
-
- /**
- * Do the basic work for finding a class. This avoids the activation detection etc
- * and can be used by subclasses to override the default (from the superclass)
- * way of finding classes.
- * @param name the class to look for
- * @return the found class
- * @throws ClassNotFoundException if the requested class cannot be found
- */
- protected Class basicFindLocalClass(String name) throws ClassNotFoundException {
- return super.findLocalClass(name);
- }
-
- /**
- * Determines if for loading the given class we should activate the bundle.
- */
- private boolean shouldActivateFor(String className) throws ClassNotFoundException {
- if (!isAutoStartable(className))
- return false;
- //Don't reactivate on shut down
- if (hostdata.getAdaptor().isStopping()) {
- BundleStopper stopper = EclipseAdaptor.getDefault().getBundleStopper();
- if (stopper != null && stopper.isStopped(hostdata.getBundle())) {
- String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_ALREADY_STOPPED, className, hostdata.getSymbolicName());
- throw new ClassNotFoundException(message);
- }
- }
- return true;
- }
-
- private boolean isAutoStartable(String className) {
- boolean autoStart = ((EclipseBundleData) hostdata).isAutoStart();
- String[] autoStartExceptions = ((EclipseBundleData) hostdata).getAutoStartExceptions();
- // no exceptions, it is easy to figure it out
- if (autoStartExceptions == null)
- return autoStart;
- // otherwise, we need to check if the package is in the exceptions list
- int dotPosition = className.lastIndexOf('.');
- // the class has no package name... no exceptions apply
- if (dotPosition == -1)
- return autoStart;
- String packageName = className.substring(0, dotPosition);
- // should activate if autoStart and package is not an exception, or if !autoStart and package is exception
- return autoStart ^ contains(autoStartExceptions, packageName);
- }
-
- private boolean contains(String[] array, String element) {
- for (int i = 0; i < array.length; i++)
- if (array[i].equals(element))
- return true;
- return false;
- }
-
- /**
- * Override defineClass to allow for package defining.
- */
- protected Class defineClass(String name, byte[] classbytes, int off, int len, ClasspathEntry classpathEntry) throws ClassFormatError {
- if (!DEFINE_PACKAGES)
- return super.defineClass(name, classbytes, off, len, classpathEntry);
-
- // Define the package if it is not the default package.
- int lastIndex = name.lastIndexOf('.');
- if (lastIndex != -1) {
- String packageName = name.substring(0, lastIndex);
- Package pkg = getPackage(packageName);
- if (pkg == null) {
- // get info about the package from the classpath entry's manifest.
- String specTitle = null, specVersion = null, specVendor = null, implTitle = null, implVersion = null, implVendor = null;
- Manifest mf = ((EclipseClasspathEntry) classpathEntry).getManifest();
- if (mf != null) {
- Attributes mainAttributes = mf.getMainAttributes();
- String dirName = packageName.replace('.', '/') + '/';
- Attributes packageAttributes = mf.getAttributes(dirName);
- boolean noEntry = false;
- if (packageAttributes == null) {
- noEntry = true;
- packageAttributes = mainAttributes;
- }
- specTitle = packageAttributes.getValue(Attributes.Name.SPECIFICATION_TITLE);
- if (specTitle == null && !noEntry)
- specTitle = mainAttributes.getValue(Attributes.Name.SPECIFICATION_TITLE);
- specVersion = packageAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
- if (specVersion == null && !noEntry)
- specVersion = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
- specVendor = packageAttributes.getValue(Attributes.Name.SPECIFICATION_VENDOR);
- if (specVendor == null && !noEntry)
- specVendor = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VENDOR);
- implTitle = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
- if (implTitle == null && !noEntry)
- implTitle = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
- implVersion = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
- if (implVersion == null && !noEntry)
- implVersion = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
- implVendor = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
- if (implVendor == null && !noEntry)
- implVendor = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
- }
- // The package is not defined yet define it before we define the class.
- // TODO still need to seal packages.
- definePackage(packageName, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, null);
- }
- }
- return super.defineClass(name, classbytes, off, len, classpathEntry);
- }
-
- private String getClassloaderId() {
- return hostdata.getBundle().getSymbolicName();
- }
-
- public URL getResource(String name) {
- URL result = super.getResource(name);
- if (StatsManager.MONITOR_RESOURCES) {
- if (result != null && name.endsWith(".properties")) { //$NON-NLS-1$
- ClassloaderStats.loadedBundle(getClassloaderId(), new ResourceBundleStats(getClassloaderId(), name, result));
- }
- }
- return result;
- }
-
- protected void findClassPathEntry(ArrayList result, String entry, AbstractBundleData bundledata, ProtectionDomain domain) {
- String var = hasPrefix(entry);
- if (var != null) {
- // find internal library using eclipse predefined vars
- findInternalClassPath(var, result, entry, bundledata, domain);
- return;
- }
- if (entry.startsWith(EXTERNAL_LIB_PREFIX)) {
- entry = entry.substring(EXTERNAL_LIB_PREFIX.length());
- // find external library using system property substitution
- ClasspathEntry cpEntry = getExternalClassPath(substituteVars(entry), bundledata, domain);
- if (cpEntry != null)
- result.add(cpEntry);
- return;
- }
- // if we get here just do the default searching
- super.findClassPathEntry(result, entry, bundledata, domain);
- }
-
- private void findInternalClassPath(String var, ArrayList result, String entry, AbstractBundleData bundledata, ProtectionDomain domain) {
- if (var.equals("ws")) { //$NON-NLS-1$
- super.findClassPathEntry(result, "ws/" + EclipseEnvironmentInfo.getDefault().getWS() + entry.substring(4), bundledata, domain); //$NON-NLS-1$
- return;
- }
- if (var.equals("os")) { //$NON-NLS-1$
- super.findClassPathEntry(result, "os/" + EclipseEnvironmentInfo.getDefault().getOS() + entry.substring(4), bundledata, domain); //$NON-NLS-1$
- return;
- }
- if (var.equals("nl")) { //$NON-NLS-1$
- entry = entry.substring(4);
- for (int i = 0; i < NL_JAR_VARIANTS.length; i++) {
- if (addClassPathEntry(result, "nl/" + NL_JAR_VARIANTS[i] + entry, bundledata, domain)) //$NON-NLS-1$
- return;
- }
- // is we are not in development mode, post some framework errors.
- if (!DevClassPathHelper.inDevelopmentMode()) {
- //BundleException be = new BundleException(Msg.formatter.getString("BUNDLE_CLASSPATH_ENTRY_NOT_FOUND_EXCEPTION", entry, hostdata.getLocation())); //$NON-NLS-1$
- BundleException be = new BundleException(NLS.bind(Msg.BUNDLE_CLASSPATH_ENTRY_NOT_FOUND_EXCEPTION, entry));
- bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), be);
- }
- }
- }
-
- private static String[] buildNLJarVariants(String nl) {
- ArrayList result = new ArrayList();
- nl = nl.replace('_', '/');
- while (nl.length() > 0) {
- result.add("nl/" + nl + "/"); //$NON-NLS-1$ //$NON-NLS-2$
- int i = nl.lastIndexOf('/');
- nl = (i < 0) ? "" : nl.substring(0, i); //$NON-NLS-1$
- }
- result.add(""); //$NON-NLS-1$
- return (String[]) result.toArray(new String[result.size()]);
- }
-
- //return a String representing the string found between the $s
- private String hasPrefix(String libPath) {
- if (libPath.startsWith("$ws$")) //$NON-NLS-1$
- return "ws"; //$NON-NLS-1$
- if (libPath.startsWith("$os$")) //$NON-NLS-1$
- return "os"; //$NON-NLS-1$
- if (libPath.startsWith("$nl$")) //$NON-NLS-1$
- return "nl"; //$NON-NLS-1$
- return null;
- }
-
- private String substituteVars(String cp) {
- StringBuffer buf = new StringBuffer(cp.length());
- StringTokenizer st = new StringTokenizer(cp, VARIABLE_DELIM_STRING, true);
- boolean varStarted = false; // indicates we are processing a var subtitute
- String var = null; // the current var key
- while (st.hasMoreElements()) {
- String tok = st.nextToken();
- if (VARIABLE_DELIM_STRING.equals(tok)) {
- if (!varStarted) {
- varStarted = true; // we found the start of a var
- var = ""; //$NON-NLS-1$
- } else {
- // we have found the end of a var
- String prop = null;
- // get the value of the var from FrameworkProperties
- if (var != null && var.length() > 0)
- prop = FrameworkProperties.getProperty(var);
- if (prop != null)
- // found a value; use it
- buf.append(prop);
- else
- // could not find a value append the var name w/o delims
- buf.append(var == null ? "" : var); //$NON-NLS-1$
- varStarted = false;
- var = null;
- }
- } else {
- if (!varStarted)
- buf.append(tok); // the token is not part of a var
- else
- var = tok; // the token is the var key; save the key to process when we find the end token
- }
- }
- if (var != null)
- // found a case of $var at the end of the cp with no trailing $; just append it as is.
- buf.append(VARIABLE_DELIM_CHAR).append(var);
- return buf.toString();
- }
-
- /**
- * Override to create EclipseClasspathEntry objects. EclipseClasspathEntry
- * allows access to the manifest file for the classpath entry.
- */
- protected ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain domain) {
- return new EclipseClasspathEntry(bundlefile, domain);
- }
-
- /**
- * A ClasspathEntry that has a manifest associated with it.
- */
- protected class EclipseClasspathEntry extends ClasspathEntry {
- Manifest mf;
- boolean initMF = false;
-
- protected EclipseClasspathEntry(BundleFile bundlefile, ProtectionDomain domain) {
- super(bundlefile, domain);
- }
-
- public Manifest getManifest() {
- if (initMF)
- return mf;
- if (!hasPackageInfo()) {
- initMF = true;
- mf = null;
- return mf;
- }
- BundleEntry mfEntry = getBundleFile().getEntry(org.eclipse.osgi.framework.internal.core.Constants.OSGI_BUNDLE_MANIFEST);
- if (mfEntry != null)
- try {
- InputStream manIn = mfEntry.getInputStream();
- mf = new Manifest(manIn);
- manIn.close();
- } catch (IOException e) {
- // do nothing
- }
- initMF = true;
- return mf;
- }
-
- private boolean hasPackageInfo() {
- if (getBundleFile() == getHostData().getBaseBundleFile())
- return ((EclipseBundleData)getHostData()).hasPackageInfo;
- FragmentClasspath[] fragCPs = getFragClasspaths();
- if (fragCPs != null)
- for (int i = 0; i < fragCPs.length; i++)
- if (getBundleFile() == fragCPs[i].getBundleData().getBaseBundleFile())
- return ((EclipseBundleData)fragCPs[i].getBundleData()).hasPackageInfo;
- return true;
- }
- }
-}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseElementFactory.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseElementFactory.java
deleted file mode 100644
index 3134a5fd0..000000000
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseElementFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2005 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.core.runtime.adaptor;
-
-import java.io.IOException;
-
-import org.eclipse.osgi.framework.adaptor.BundleProtectionDomain;
-import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
-import org.eclipse.osgi.framework.adaptor.core.*;
-
-/**
- * Creates EclipseBundleData and EclipseClassLoader objects for the framework adaptor
- * <p>
- * Clients may extend this class.
- * </p>
- * @since 3.1
- */
-public class EclipseElementFactory implements AdaptorElementFactory {
-
- public AbstractBundleData createBundleData(AbstractFrameworkAdaptor adaptor, long id) throws IOException {
- return new EclipseBundleData((AbstractFrameworkAdaptor) adaptor, id);
- }
-
- public org.eclipse.osgi.framework.adaptor.BundleClassLoader createClassLoader(ClassLoaderDelegate delegate, BundleProtectionDomain domain, String[] bundleclasspath, AbstractBundleData data) {
- return new EclipseClassLoader(delegate, domain, bundleclasspath, data.getAdaptor().getBundleClassLoaderParent(), data);
- }
-
-}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseStarter.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseStarter.java
index 965597ff7..e7d74cb2d 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseStarter.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseStarter.java
@@ -118,7 +118,7 @@ public class EclipseStarter {
private static final String REFERENCE_PROTOCOL = "reference"; //$NON-NLS-1$
private static final String INITIAL_LOCATION = "initial@"; //$NON-NLS-1$
/** string containing the classname of the adaptor to be used in this framework instance */
- protected static final String DEFAULT_ADAPTOR_CLASS = "org.eclipse.core.runtime.adaptor.EclipseAdaptor"; //$NON-NLS-1$
+ protected static final String DEFAULT_ADAPTOR_CLASS = "org.eclipse.osgi.baseadaptor.BaseAdaptor"; //$NON-NLS-1$
private static final int DEFAULT_INITIAL_STARTLEVEL = 6; // default value for legacy purposes
private static final String DEFAULT_BUNDLES_STARTLEVEL = "4"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/BundleStopper.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/BundleStopper.java
index 417cc7aff..a3d70895e 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/BundleStopper.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/BundleStopper.java
@@ -4,14 +4,14 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.runtime.internal.adaptor;
import java.util.Hashtable;
-import org.eclipse.core.runtime.adaptor.*;
+import org.eclipse.osgi.baseadaptor.BaseData;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
import org.eclipse.osgi.framework.debug.Debug;
import org.eclipse.osgi.framework.internal.core.AbstractBundle;
@@ -33,18 +33,19 @@ import org.osgi.framework.BundleContext;
public class BundleStopper {
/* must be a synchronized object */
private Hashtable stoppedBundles;
-
private BundleDescription[] allToStop = null;
-
private BundleContext context;
+ private FrameworkAdaptor adaptor;
- public BundleStopper(BundleContext context) {
+ public BundleStopper(BundleContext context, FrameworkAdaptor adaptor) {
this.context = context;
+ this.adaptor = adaptor;
}
private void logCycles(Object[][] cycles) {
if (!Debug.DEBUG || !Debug.DEBUG_ENABLED)
return;
+
// log cycles
if (cycles.length > 0) {
StringBuffer cycleText = new StringBuffer("["); //$NON-NLS-1$
@@ -57,15 +58,15 @@ public class BundleStopper {
cycleText.insert(cycleText.length() - 1, ']');
}
cycleText.setCharAt(cycleText.length() - 1, ']');
- String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_BUNDLESTOPPER_CYCLES_FOUND, cycleText);
+ String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_BUNDLESTOPPER_CYCLES_FOUND, cycleText);
FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.WARNING, 0, message, 0, null, null);
- EclipseAdaptor.getDefault().getFrameworkLog().log(entry);
+ adaptor.getFrameworkLog().log(entry);
}
}
public void stopBundles() {
- allToStop = EclipseAdaptor.getDefault().getState().getResolvedBundles();
- StateHelper stateHelper = EclipseAdaptor.getDefault().getPlatformAdmin().getStateHelper();
+ allToStop = adaptor.getState().getResolvedBundles();
+ StateHelper stateHelper = adaptor.getPlatformAdmin().getStateHelper();
Object[][] cycles = stateHelper.sortBundles(allToStop);
logCycles(cycles);
stoppedBundles = new Hashtable(allToStop.length);
@@ -76,14 +77,16 @@ public class BundleStopper {
// stop all active bundles in the reverse order of Require-Bundle
for (int stoppingIndex = allToStop.length - 1; stoppingIndex >= 0; stoppingIndex--) {
AbstractBundle toStop = (AbstractBundle) context.getBundle(allToStop[stoppingIndex].getBundleId());
- if (toStop.getBundleId() != 0 && ((EclipseBundleData) toStop.getBundleData()).isAutoStartable()) {
+ BaseData bundledata = (BaseData) toStop.getBundleData();
+ EclipseStorageHook storageHook = (EclipseStorageHook) bundledata.getStorageHook(EclipseStorageHook.KEY);
+ if (toStop.getBundleId() != 0 && storageHook != null && storageHook.isAutoStartable()) {
try {
if ((toStop.getState() == Bundle.ACTIVE) && (toStop instanceof BundleHost))
toStop.stop();
} catch (Exception e) {
String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_BUNDLESTOPPER_ERROR_STOPPING_BUNDLE, allToStop[stoppingIndex].toString());
FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, e, null);
- EclipseAdaptor.getDefault().getFrameworkLog().log(entry);
+ adaptor.getFrameworkLog().log(entry);
} finally {
stoppedBundles.put(toStop, toStop);
}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/CachedManifest.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/CachedManifest.java
index a460b8abf..1056b86ed 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/CachedManifest.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/CachedManifest.java
@@ -4,7 +4,7 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
@@ -12,7 +12,6 @@ package org.eclipse.core.runtime.internal.adaptor;
import java.util.Dictionary;
import java.util.Enumeration;
-import org.eclipse.core.runtime.adaptor.*;
import org.eclipse.osgi.framework.adaptor.BundleData;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
import org.eclipse.osgi.framework.internal.core.Constants;
@@ -25,21 +24,21 @@ import org.osgi.framework.*;
*/
public class CachedManifest extends Dictionary {
- Dictionary manifest = null;
- EclipseBundleData bundledata;
+ private Dictionary manifest = null;
+ private EclipseStorageHook storageHook;
- public CachedManifest(EclipseBundleData bundledata) {
- this.bundledata = bundledata;
+ public CachedManifest(EclipseStorageHook storageHook) {
+ this.storageHook = storageHook;
}
public Dictionary getManifest() {
if (manifest == null)
try {
- manifest = bundledata.loadManifest();
+ manifest = storageHook.createCachedManifest(true);
} catch (BundleException e) {
- final String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CACHEDMANIFEST_UNEXPECTED_EXCEPTION, bundledata.getLocation());
+ final String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CACHEDMANIFEST_UNEXPECTED_EXCEPTION, storageHook.getBaseData().getLocation());
FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, e, null);
- EclipseAdaptor.getDefault().getFrameworkLog().log(entry);
+ storageHook.getAdaptor().getFrameworkLog().log(entry);
return null;
}
return manifest;
@@ -67,20 +66,20 @@ public class CachedManifest extends Dictionary {
public Object get(Object key) {
String keyString = (String) key;
if (Constants.BUNDLE_VERSION.equalsIgnoreCase(keyString)) {
- Version result = bundledata.getVersion();
+ Version result = storageHook.getBaseData().getVersion();
return result == null ? null : result.toString();
}
- if (EclipseAdaptor.PLUGIN_CLASS.equalsIgnoreCase(keyString))
- return bundledata.getPluginClass();
+ if (Constants.PLUGIN_CLASS.equalsIgnoreCase(keyString))
+ return storageHook.getPluginClass();
if (Constants.BUNDLE_SYMBOLICNAME.equalsIgnoreCase(keyString)) {
- if ((bundledata.getType() & BundleData.TYPE_SINGLETON) == 0)
- return bundledata.getSymbolicName();
- return bundledata.getSymbolicName() + ';' + Constants.SINGLETON_DIRECTIVE + ":=true"; //$NON-NLS-1$
+ if ((storageHook.getBaseData().getType() & BundleData.TYPE_SINGLETON) == 0)
+ return storageHook.getBaseData().getSymbolicName();
+ return storageHook.getBaseData().getSymbolicName() + ';' + Constants.SINGLETON_DIRECTIVE + ":=true"; //$NON-NLS-1$
}
if (Constants.BUDDY_LOADER.equalsIgnoreCase(keyString))
- return bundledata.getBuddyList();
+ return storageHook.getBuddyList();
if (Constants.REGISTERED_POLICY.equalsIgnoreCase(keyString))
- return bundledata.getRegisteredBuddyList();
+ return storageHook.getRegisteredBuddyList();
Dictionary result = getManifest();
return result == null ? null : result.get(key);
}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/ClasspathManifest.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/ClasspathManifest.java
new file mode 100644
index 000000000..200c365c3
--- /dev/null
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/ClasspathManifest.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.core.runtime.internal.adaptor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.jar.Manifest;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.loader.*;
+import org.eclipse.osgi.framework.util.KeyedElement;
+
+public class ClasspathManifest implements KeyedElement {
+ public static final Object KEY = new Object();
+ public static final int HASHCODE = KEY.hashCode();
+
+ private Manifest manifest;
+ private boolean initialized = false;
+
+ public int getKeyHashCode() {
+ return HASHCODE;
+ }
+
+ public boolean compare(KeyedElement other) {
+ return other.getKey() == KEY;
+ }
+
+ public Object getKey() {
+ return KEY;
+ }
+
+ public Manifest getManifest(ClasspathEntry cpEntry, ClasspathManager loader) {
+ if (initialized)
+ return manifest;
+ if (!hasPackageInfo(cpEntry, loader)) {
+ initialized = true;
+ manifest = null;
+ return manifest;
+ }
+ BundleEntry mfEntry = cpEntry.getBundleFile().getEntry(org.eclipse.osgi.framework.internal.core.Constants.OSGI_BUNDLE_MANIFEST);
+ if (mfEntry != null)
+ try {
+ InputStream manIn = mfEntry.getInputStream();
+ manifest = new Manifest(manIn);
+ manIn.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ initialized = true;
+ return manifest;
+ }
+
+ private boolean hasPackageInfo(ClasspathEntry cpEntry, ClasspathManager loader) {
+ BaseData bundledata = null;
+ if (cpEntry.getBundleFile() == loader.getBaseData().getBundleFile())
+ bundledata = loader.getBaseData();
+ if (bundledata == null) {
+ FragmentClasspath[] fragCPs = loader.getFragmentClasspaths();
+ if (fragCPs != null)
+ for (int i = 0; i < fragCPs.length; i++)
+ if (cpEntry.getBundleFile() == fragCPs[i].getBundleData().getBundleFile()) {
+ bundledata = fragCPs[i].getBundleData();
+ break;
+ }
+ }
+ if (bundledata == null)
+ return true;
+ EclipseStorageHook storageHook = (EclipseStorageHook) bundledata.getStorageHook(EclipseStorageHook.KEY);
+ return storageHook == null ? true : storageHook.hasPackageInfo();
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorHook.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorHook.java
new file mode 100644
index 000000000..293e41297
--- /dev/null
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorHook.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.core.runtime.internal.adaptor;
+
+import java.io.*;
+import java.net.URLConnection;
+import java.util.*;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.SAXParserFactory;
+import org.eclipse.core.runtime.adaptor.LocationManager;
+import org.eclipse.osgi.baseadaptor.*;
+import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook;
+import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
+import org.eclipse.osgi.framework.console.CommandProvider;
+import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.framework.debug.FrameworkDebugOptions;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.framework.log.FrameworkLog;
+import org.eclipse.osgi.framework.log.FrameworkLogEntry;
+import org.eclipse.osgi.internal.baseadaptor.AdaptorUtil;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.eclipse.osgi.service.pluginconversion.PluginConverter;
+import org.eclipse.osgi.service.resolver.PlatformAdmin;
+import org.eclipse.osgi.service.runnable.ApplicationLauncher;
+import org.eclipse.osgi.service.urlconversion.URLConverter;
+import org.osgi.framework.*;
+
+public class EclipseAdaptorHook implements AdaptorHook, HookConfigurator {
+ /** The SAX factory name */
+ public static final String SAXFACTORYNAME = "javax.xml.parsers.SAXParserFactory"; //$NON-NLS-1$
+ /** The DOM factory name */
+ public static final String DOMFACTORYNAME = "javax.xml.parsers.DocumentBuilderFactory"; //$NON-NLS-1$
+ private static final String RUNTIME_ADAPTOR = FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + "/eclipseadaptor"; //$NON-NLS-1$
+ private static final String OPTION_CONVERTER = RUNTIME_ADAPTOR + "/converter/debug"; //$NON-NLS-1$
+ private static final String OPTION_LOCATION = RUNTIME_ADAPTOR + "/debug/location"; //$NON-NLS-1$
+
+ private BaseAdaptor adaptor;
+ private BundleStopper stopper;
+ private boolean noXML = false;
+
+ public void frameworkStart(BundleContext context) throws BundleException {
+ stopper = null;
+ registerEndorsedXMLParser(context);
+ Location location = LocationManager.getUserLocation();
+ Hashtable locationProperties = new Hashtable(1);
+ if (location != null) {
+ locationProperties.put("type", LocationManager.PROP_USER_AREA); //$NON-NLS-1$
+ context.registerService(Location.class.getName(), location, locationProperties);
+ }
+ location = LocationManager.getInstanceLocation();
+ if (location != null) {
+ locationProperties.put("type", LocationManager.PROP_INSTANCE_AREA); //$NON-NLS-1$
+ context.registerService(Location.class.getName(), location, locationProperties);
+ }
+ location = LocationManager.getConfigurationLocation();
+ if (location != null) {
+ locationProperties.put("type", LocationManager.PROP_CONFIG_AREA); //$NON-NLS-1$
+ context.registerService(Location.class.getName(), location, locationProperties);
+ }
+ location = LocationManager.getInstallLocation();
+ if (location != null) {
+ locationProperties.put("type", LocationManager.PROP_INSTALL_AREA); //$NON-NLS-1$
+ context.registerService(Location.class.getName(), location, locationProperties);
+ }
+
+ Dictionary urlProperties = new Hashtable();
+ urlProperties.put("protocol", new String[] {"bundleentry", "bundleresource"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ context.registerService(URLConverter.class.getName(), new URLConverterImpl(), urlProperties);
+
+ AdaptorUtil.register(org.eclipse.osgi.service.environment.EnvironmentInfo.class.getName(), EclipseEnvironmentInfo.getDefault(), context);
+ AdaptorUtil.register(PlatformAdmin.class.getName(), adaptor.getPlatformAdmin(), context);
+ PluginConverter converter = PluginConverterImpl.getDefault();
+ if (converter == null)
+ converter = new PluginConverterImpl(adaptor, context);
+ AdaptorUtil.register(PluginConverter.class.getName(), converter, context);
+ AdaptorUtil.register(CommandProvider.class.getName(), new EclipseCommandProvider(context), context);
+ AdaptorUtil.register(org.eclipse.osgi.service.localization.BundleLocalization.class.getName(), new BundleLocalizationImpl(), context);
+ }
+
+ private void registerEndorsedXMLParser(BundleContext bc) {
+ try {
+ Class.forName(SAXFACTORYNAME);
+ bc.registerService(SAXFACTORYNAME, new SaxParsingService(), new Hashtable());
+ Class.forName(DOMFACTORYNAME);
+ bc.registerService(DOMFACTORYNAME, new DomParsingService(), new Hashtable());
+ } catch (ClassNotFoundException e) {
+ noXML = true;
+ if (Debug.DEBUG && Debug.DEBUG_ENABLED) {
+ String message = EclipseAdaptorMsg.ECLIPSE_ADAPTOR_ERROR_XML_SERVICE;
+ adaptor.getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, e, null));
+ }
+ }
+ }
+
+ private class SaxParsingService implements ServiceFactory {
+ public Object getService(Bundle bundle, ServiceRegistration registration) {
+ return SAXParserFactory.newInstance();
+ }
+
+ public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+ // Do nothing.
+ }
+ }
+
+ private class DomParsingService implements ServiceFactory {
+ public Object getService(Bundle bundle, ServiceRegistration registration) {
+ return DocumentBuilderFactory.newInstance();
+ }
+
+ public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+ // Do nothing.
+ }
+ }
+
+ public void frameworkStop(BundleContext context) throws BundleException {
+ // TODO should unregister the services here
+ printStats();
+ if (!noXML)
+ PluginParser.releaseXMLParsing();
+ }
+
+ private void printStats() {
+ FrameworkDebugOptions debugOptions = FrameworkDebugOptions.getDefault();
+ if (debugOptions == null)
+ return;
+ String registryParsing = debugOptions.getOption("org.eclipse.core.runtime/registry/parsing/timing/value"); //$NON-NLS-1$
+ if (registryParsing != null)
+ EclipseAdaptorMsg.debug("Time spent in registry parsing: " + registryParsing); //$NON-NLS-1$
+ String packageAdminResolution = debugOptions.getOption("debug.packageadmin/timing/value"); //$NON-NLS-1$
+ if (packageAdminResolution != null)
+ System.out.println("Time spent in package admin resolve: " + packageAdminResolution); //$NON-NLS-1$
+ String constraintResolution = debugOptions.getOption("org.eclipse.core.runtime.adaptor/resolver/timing/value"); //$NON-NLS-1$
+ if (constraintResolution != null)
+ System.out.println("Time spent resolving the dependency system: " + constraintResolution); //$NON-NLS-1$
+ }
+
+ public void frameworkStopping(BundleContext context) {
+ // Shutdown the ApplicationLauncher service if it is available.
+ ServiceReference launcherRef = context.getServiceReference(ApplicationLauncher.class.getName());
+ if (launcherRef != null) {
+ ApplicationLauncher launcher = (ApplicationLauncher) context.getService(launcherRef);
+ // this will force a currently running application to stop.
+ launcher.shutdown();
+ context.ungetService(launcherRef);
+ }
+ stopper = new BundleStopper(context, adaptor);
+ stopper.stopBundles();
+ }
+
+ public void addProperties(Properties properties) {
+ // default the bootdelegation to all packages
+ if (properties.getProperty(Constants.OSGI_BOOTDELEGATION) == null && !Constants.OSGI_BOOTDELEGATION_NONE.equals(properties.getProperty(Constants.OSGI_JAVA_PROFILE_BOOTDELEGATION)))
+ properties.put(Constants.OSGI_BOOTDELEGATION, "*"); //$NON-NLS-1$
+ if (properties.getProperty(Constants.ECLIPSE_EE_INSTALL_VERIFY) == null)
+ properties.put(Constants.ECLIPSE_EE_INSTALL_VERIFY, "false"); //$NON-NLS-1$
+ }
+
+ public URLConnection mapLocationToURLConnection(String location) throws IOException {
+ // do nothing
+ return null;
+ }
+
+ public void handleRuntimeError(Throwable error) {
+ // do nothing
+ }
+
+ public boolean matchDNChain(String pattern, String[] dnChain) {
+ // do nothing
+ return false;
+ }
+
+ public FrameworkLog createFrameworkLog() {
+ // do nothing
+ return null;
+ }
+
+ public void initialize(BaseAdaptor adaptor) {
+ this.adaptor = adaptor;
+ // EnvironmentInfo has to be initialized first to compute defaults for system context (see bug 88925)
+ EclipseEnvironmentInfo.getDefault();
+ setDebugOptions();
+ }
+
+ private void setDebugOptions() {
+ FrameworkDebugOptions options = FrameworkDebugOptions.getDefault();
+ // may be null if debugging is not enabled
+ if (options == null)
+ return;
+ PluginConverterImpl.DEBUG = options.getBooleanOption(OPTION_CONVERTER, false);
+ BasicLocation.DEBUG = options.getBooleanOption(OPTION_LOCATION, false);
+ }
+
+ public BundleStopper getBundleStopper() {
+ return stopper;
+ }
+
+ public void addHooks(HookRegistry hookRegistry) {
+ hookRegistry.addAdaptorHook(this);
+ }
+
+}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMessages.properties b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMessages.properties
index a9887e71e..a9887e71e 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMessages.properties
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMessages.properties
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMsg.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMsg.java
index 37437967a..1c2db825a 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseAdaptorMsg.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMsg.java
@@ -8,14 +8,14 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
-package org.eclipse.core.runtime.adaptor;
+package org.eclipse.core.runtime.internal.adaptor;
import java.util.Date;
import org.eclipse.osgi.service.resolver.*;
import org.eclipse.osgi.util.NLS;
public class EclipseAdaptorMsg extends NLS {
- private static final String BUNDLE_NAME = "org.eclipse.core.runtime.adaptor.EclipseAdaptorMessages"; //$NON-NLS-1$
+ private static final String BUNDLE_NAME = "org.eclipse.core.runtime.internal.adaptor.EclipseAdaptorMessages"; //$NON-NLS-1$
public static String ECLIPSE_MISSING_IMPORTED_PACKAGE;
public static String ECLIPSE_MISSING_OPTIONAL_REQUIRED_BUNDLE;
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAppLauncher.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAppLauncher.java
index b0e46fedf..6ca014891 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAppLauncher.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseAppLauncher.java
@@ -11,7 +11,6 @@
package org.eclipse.core.runtime.internal.adaptor;
-import org.eclipse.core.runtime.adaptor.EclipseAdaptorMsg;
import org.eclipse.core.runtime.adaptor.EclipseStarter;
import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
import org.eclipse.osgi.internal.profile.Profile;
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseBundleInstaller.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseBundleInstaller.java
deleted file mode 100644
index d78998cb5..000000000
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseBundleInstaller.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.core.runtime.internal.adaptor;
-
-import org.eclipse.osgi.framework.adaptor.core.BundleInstaller;
-import org.eclipse.osgi.service.resolver.BundleDescription;
-import org.osgi.framework.*;
-
-/**
- * Internal class.
- */
-//TODO: minimal implementation for now. This could be smarter
-public class EclipseBundleInstaller implements BundleInstaller {
- BundleContext context;
- public EclipseBundleInstaller(BundleContext context) {
- this.context = context;
- }
-
- public void installBundle(BundleDescription toInstall) throws BundleException {
- context.installBundle(toInstall.getLocation());
- }
-
- public void uninstallBundle(BundleDescription toUninstallId) throws BundleException {
- Bundle toUninstall = context.getBundle(toUninstallId.getBundleId());
- if (toUninstall != null)
- toUninstall.uninstall();
- }
-
- public void updateBundle(BundleDescription toUpdateId) throws BundleException {
- Bundle toUpdate = context.getBundle(toUpdateId.getBundleId());
- if (toUpdate != null)
- toUpdate.update();
- }
-}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseClassLoadingHook.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseClassLoadingHook.java
new file mode 100644
index 000000000..bb634ad1c
--- /dev/null
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseClassLoadingHook.java
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.core.runtime.internal.adaptor;
+
+import java.io.File;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import org.eclipse.osgi.baseadaptor.*;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
+import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook;
+import org.eclipse.osgi.baseadaptor.loader.*;
+import org.eclipse.osgi.framework.adaptor.BundleProtectionDomain;
+import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
+import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
+
+public class EclipseClassLoadingHook implements ClassLoadingHook, HookConfigurator {
+ private static String[] NL_JAR_VARIANTS = buildNLJarVariants(EclipseEnvironmentInfo.getDefault().getNL());
+ private static boolean DEFINE_PACKAGES;
+ private static final String VARIABLE_DELIM_STRING = "$"; //$NON-NLS-1$
+ private static final char VARIABLE_DELIM_CHAR = '$';
+ private static final String EXTERNAL_LIB_PREFIX = "external:"; //$NON-NLS-1$
+ private static String[] LIB_VARIANTS = buildLibraryVariants();
+
+ static {
+ try {
+ Class.forName("java.lang.Package"); //$NON-NLS-1$
+ DEFINE_PACKAGES = true;
+ } catch (ClassNotFoundException e) {
+ DEFINE_PACKAGES = false;
+ }
+ }
+
+ private static String[] buildLibraryVariants() {
+ ArrayList result = new ArrayList();
+ EclipseEnvironmentInfo info = EclipseEnvironmentInfo.getDefault();
+ result.add("ws/" + info.getWS() + "/"); //$NON-NLS-1$ //$NON-NLS-2$
+ result.add("os/" + info.getOS() + "/" + info.getOSArch() + "/"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ result.add("os/" + info.getOS() + "/"); //$NON-NLS-1$ //$NON-NLS-2$
+ String nl = info.getNL();
+ nl = nl.replace('_', '/');
+ while (nl.length() > 0) {
+ result.add("nl/" + nl + "/"); //$NON-NLS-1$ //$NON-NLS-2$
+ int i = nl.lastIndexOf('/');
+ nl = (i < 0) ? "" : nl.substring(0, i); //$NON-NLS-1$
+ }
+ result.add(""); //$NON-NLS-1$
+ return (String[]) result.toArray(new String[result.size()]);
+ }
+
+ public byte[] processClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
+ if (!DEFINE_PACKAGES)
+ return null;
+ // Define the package if it is not the default package.
+ int lastIndex = name.lastIndexOf('.');
+ if (lastIndex < 0)
+ return null;
+ String packageName = name.substring(0, lastIndex);
+ Package pkg = (Package) manager.getBaseClassLoader().publicGetPackage(packageName);
+ if (pkg != null)
+ return null;
+
+ // get info about the package from the classpath entry's manifest.
+ String specTitle = null, specVersion = null, specVendor = null, implTitle = null, implVersion = null, implVendor = null;
+ ClasspathManifest cpm = (ClasspathManifest) classpathEntry.getUserObject(ClasspathManifest.KEY);
+ if (cpm == null) {
+ cpm = new ClasspathManifest();
+ classpathEntry.addUserObject(cpm);
+ }
+ Manifest mf = cpm.getManifest(classpathEntry, manager);
+ if (mf != null) {
+ Attributes mainAttributes = mf.getMainAttributes();
+ String dirName = packageName.replace('.', '/') + '/';
+ Attributes packageAttributes = mf.getAttributes(dirName);
+ boolean noEntry = false;
+ if (packageAttributes == null) {
+ noEntry = true;
+ packageAttributes = mainAttributes;
+ }
+ specTitle = packageAttributes.getValue(Attributes.Name.SPECIFICATION_TITLE);
+ if (specTitle == null && !noEntry)
+ specTitle = mainAttributes.getValue(Attributes.Name.SPECIFICATION_TITLE);
+ specVersion = packageAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
+ if (specVersion == null && !noEntry)
+ specVersion = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
+ specVendor = packageAttributes.getValue(Attributes.Name.SPECIFICATION_VENDOR);
+ if (specVendor == null && !noEntry)
+ specVendor = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VENDOR);
+ implTitle = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
+ if (implTitle == null && !noEntry)
+ implTitle = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
+ implVersion = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
+ if (implVersion == null && !noEntry)
+ implVersion = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
+ implVendor = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
+ if (implVendor == null && !noEntry)
+ implVendor = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
+ }
+ // The package is not defined yet define it before we define the class.
+ // TODO still need to seal packages.
+ manager.getBaseClassLoader().publicDefinePackage(packageName, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, null);
+ // not doing any byte processing
+ return null;
+ }
+
+ public boolean addClassPathEntry(ArrayList cpEntries, String cp, ClasspathManager hostmanager, BaseData sourcedata, ProtectionDomain sourcedomain) {
+ String var = hasPrefix(cp);
+ if (var != null)
+ // find internal library using eclipse predefined vars
+ return addInternalClassPath(var, cpEntries, cp, hostmanager, sourcedata, sourcedomain);
+ if (cp.startsWith(EXTERNAL_LIB_PREFIX)) {
+ cp = cp.substring(EXTERNAL_LIB_PREFIX.length());
+ // find external library using system property substitution
+ ClasspathEntry cpEntry = hostmanager.getExternalClassPath(substituteVars(cp), sourcedata, sourcedomain);
+ if (cpEntry != null) {
+ cpEntries.add(cpEntry);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean addInternalClassPath(String var, ArrayList cpEntries, String cp, ClasspathManager hostloader, BaseData sourcedata, ProtectionDomain sourcedomain) {
+ if (var.equals("ws")) //$NON-NLS-1$
+ return ClasspathManager.addClassPathEntry(cpEntries, "ws/" + EclipseEnvironmentInfo.getDefault().getWS() + cp.substring(4), hostloader, sourcedata, sourcedomain); //$NON-NLS-1$
+ if (var.equals("os")) //$NON-NLS-1$
+ return ClasspathManager.addClassPathEntry(cpEntries, "os/" + EclipseEnvironmentInfo.getDefault().getOS() + cp.substring(4), hostloader, sourcedata, sourcedomain); //$NON-NLS-1$
+ if (var.equals("nl")) { //$NON-NLS-1$
+ cp = cp.substring(4);
+ for (int i = 0; i < NL_JAR_VARIANTS.length; i++)
+ if (ClasspathManager.addClassPathEntry(cpEntries, "nl/" + NL_JAR_VARIANTS[i] + cp, hostloader, sourcedata, sourcedomain)) //$NON-NLS-1$
+ return true;
+ }
+ return false;
+ }
+
+ //return a String representing the string found between the $s
+ private static String hasPrefix(String libPath) {
+ if (libPath.startsWith("$ws$")) //$NON-NLS-1$
+ return "ws"; //$NON-NLS-1$
+ if (libPath.startsWith("$os$")) //$NON-NLS-1$
+ return "os"; //$NON-NLS-1$
+ if (libPath.startsWith("$nl$")) //$NON-NLS-1$
+ return "nl"; //$NON-NLS-1$
+ return null;
+ }
+
+ private static String substituteVars(String cp) {
+ StringBuffer buf = new StringBuffer(cp.length());
+ StringTokenizer st = new StringTokenizer(cp, VARIABLE_DELIM_STRING, true);
+ boolean varStarted = false; // indicates we are processing a var subtitute
+ String var = null; // the current var key
+ while (st.hasMoreElements()) {
+ String tok = st.nextToken();
+ if (VARIABLE_DELIM_STRING.equals(tok)) {
+ if (!varStarted) {
+ varStarted = true; // we found the start of a var
+ var = ""; //$NON-NLS-1$
+ } else {
+ // we have found the end of a var
+ String prop = null;
+ // get the value of the var from system properties
+ if (var != null && var.length() > 0)
+ prop = FrameworkProperties.getProperty(var);
+ if (prop != null)
+ // found a value; use it
+ buf.append(prop);
+ else
+ // could not find a value append the var name w/o delims
+ buf.append(var == null ? "" : var); //$NON-NLS-1$
+ varStarted = false;
+ var = null;
+ }
+ } else {
+ if (!varStarted)
+ buf.append(tok); // the token is not part of a var
+ else
+ var = tok; // the token is the var key; save the key to process when we find the end token
+ }
+ }
+ if (var != null)
+ // found a case of $var at the end of the cp with no trailing $; just append it as is.
+ buf.append(VARIABLE_DELIM_CHAR).append(var);
+ return buf.toString();
+ }
+
+ private static String[] buildNLJarVariants(String nl) {
+ ArrayList result = new ArrayList();
+ nl = nl.replace('_', '/');
+ while (nl.length() > 0) {
+ result.add("nl/" + nl + "/"); //$NON-NLS-1$ //$NON-NLS-2$
+ int i = nl.lastIndexOf('/');
+ nl = (i < 0) ? "" : nl.substring(0, i); //$NON-NLS-1$
+ }
+ result.add(""); //$NON-NLS-1$
+ return (String[]) result.toArray(new String[result.size()]);
+ }
+
+ public void recordClassDefine(String name, Class clazz, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
+ // do nothing
+ }
+
+ public String findLibrary(BaseData data, String libName) {
+ if (libName.length() == 0)
+ return null;
+ if (libName.charAt(0) == '/' || libName.charAt(0) == '\\')
+ libName = libName.substring(1);
+ libName = System.mapLibraryName(libName);
+ return searchVariants(data, libName);
+ }
+
+ private String searchVariants(BaseData bundledata, String path) {
+ for (int i = 0; i < LIB_VARIANTS.length; i++) {
+ BundleFile baseBundleFile = bundledata.getBundleFile();
+ BundleEntry libEntry = baseBundleFile.getEntry(LIB_VARIANTS[i] + path);
+ if (libEntry != null) {
+ File libFile = baseBundleFile.getFile(LIB_VARIANTS[i] + path, true);
+ if (libFile == null)
+ return null;
+ // see bug 88697 - HP requires libraries to have executable permissions
+ if (org.eclipse.osgi.service.environment.Constants.OS_HPUX.equals(EclipseEnvironmentInfo.getDefault().getOS())) {
+ try {
+ // use the string array method in case there is a space in the path
+ Runtime.getRuntime().exec(new String[] {"chmod", "755", libFile.getAbsolutePath()}).waitFor(); //$NON-NLS-1$ //$NON-NLS-2$
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return libFile.getAbsolutePath();
+ }
+ }
+ return null;
+ }
+
+ public ClassLoader getBundleClassLoaderParent() {
+ return null; // do nothing
+ }
+
+ public void addHooks(HookRegistry hookRegistry) {
+ hookRegistry.addClassLoadingHook(this);
+ }
+
+ public BaseClassLoader createClassLoader(ClassLoader parent, ClassLoaderDelegate delegate, BundleProtectionDomain domain, BaseData data, String[] bundleclasspath) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void initializedClassLoader(BaseClassLoader baseClassLoader, BaseData data) {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseCommandProvider.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseCommandProvider.java
index 6409629a5..c9bbacc73 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseCommandProvider.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseCommandProvider.java
@@ -12,7 +12,6 @@ package org.eclipse.core.runtime.internal.adaptor;
import java.util.Enumeration;
import java.util.Properties;
-import org.eclipse.core.runtime.adaptor.EclipseAdaptorMsg;
import org.eclipse.osgi.framework.console.CommandInterpreter;
import org.eclipse.osgi.framework.console.CommandProvider;
import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseEnvironmentInfo.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseEnvironmentInfo.java
index a6befb2d4..4d01f1878 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseEnvironmentInfo.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseEnvironmentInfo.java
@@ -11,7 +11,6 @@
package org.eclipse.core.runtime.internal.adaptor;
import java.util.*;
-import org.eclipse.core.runtime.adaptor.EclipseAdaptorMsg;
import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
import org.eclipse.osgi.service.environment.Constants;
import org.eclipse.osgi.service.environment.EnvironmentInfo;
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseErrorHandler.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseErrorHandler.java
new file mode 100644
index 000000000..bc60f224a
--- /dev/null
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseErrorHandler.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.core.runtime.internal.adaptor;
+
+import java.io.IOException;
+import java.net.URLConnection;
+import java.util.Properties;
+import org.eclipse.osgi.baseadaptor.*;
+import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook;
+import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
+import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
+import org.eclipse.osgi.framework.log.FrameworkLog;
+import org.eclipse.osgi.framework.log.FrameworkLogEntry;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+
+public class EclipseErrorHandler implements AdaptorHook, HookConfigurator {
+ // System property used to prevent VM exit when unexpected errors occur
+ private static final String PROP_EXITONERROR = "eclipse.exitOnError"; //$NON-NLS-1$
+ private BaseAdaptor adaptor;
+
+ public void frameworkStart(BundleContext context) throws BundleException {
+ // do nothing
+ }
+
+ public void frameworkStop(BundleContext context) throws BundleException {
+ // do nothing
+ }
+
+ public void frameworkStopping(BundleContext context) {
+ // do nothing
+ }
+
+ public void addProperties(Properties properties) {
+ // do nothing
+ }
+
+ public URLConnection mapLocationToURLConnection(String location) throws IOException {
+ // do nothing
+ return null;
+ }
+
+ private boolean isFatalException(Throwable error) {
+ if (error instanceof VirtualMachineError) {
+ return true;
+ }
+ if (error instanceof ThreadDeath) {
+ return true;
+ }
+ return false;
+ }
+
+ public void handleRuntimeError(Throwable error) {
+ // this is the important method to handle errors
+ boolean exitOnError = false;
+ try {
+ // check the prop each time this happens (should NEVER happen!)
+ exitOnError = Boolean.valueOf(FrameworkProperties.getProperty(EclipseErrorHandler.PROP_EXITONERROR, "true")).booleanValue(); //$NON-NLS-1$
+ String message = EclipseAdaptorMsg.ECLIPSE_ADAPTOR_RUNTIME_ERROR;
+ if (exitOnError && isFatalException(error))
+ message += ' ' + EclipseAdaptorMsg.ECLIPSE_ADAPTOR_EXITING;
+ FrameworkLogEntry logEntry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, error, null);
+ adaptor.getFrameworkLog().log(logEntry);
+ } catch (Throwable t) {
+ // we may be in a currupted state and must be able to handle any
+ // errors (ie OutOfMemoryError)
+ // that may occur when handling the first error; this is REALLY the
+ // last resort.
+ try {
+ error.printStackTrace();
+ t.printStackTrace();
+ } catch (Throwable t1) {
+ // if we fail that then we are beyond help.
+ }
+ } finally {
+ // do the exit outside the try block just incase another runtime
+ // error was thrown while logging
+ if (exitOnError && isFatalException(error))
+ System.exit(13);
+ }
+ }
+
+ public boolean matchDNChain(String pattern, String[] dnChain) {
+ // do nothing
+ return false;
+ }
+
+ public void addHooks(HookRegistry hookRegistry) {
+ hookRegistry.addAdaptorHook(this);
+ }
+
+ public FrameworkLog createFrameworkLog() {
+ // do nothing
+ return null;
+ }
+
+ public void initialize(BaseAdaptor adaptor) {
+ this.adaptor = adaptor;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLazyStarter.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLazyStarter.java
new file mode 100644
index 000000000..a1a5190a3
--- /dev/null
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLazyStarter.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.core.runtime.internal.adaptor;
+
+import java.net.URL;
+import org.eclipse.core.runtime.internal.stats.StatsManager;
+import org.eclipse.osgi.baseadaptor.*;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook;
+import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingStatsHook;
+import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry;
+import org.eclipse.osgi.baseadaptor.loader.ClasspathManager;
+import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
+import org.eclipse.osgi.framework.internal.core.AbstractBundle;
+import org.eclipse.osgi.framework.log.FrameworkLogEntry;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+
+public class EclipseLazyStarter implements ClassLoadingStatsHook, HookConfigurator {
+
+ public void preFindLocalClass(String name, ClasspathManager manager) throws ClassNotFoundException {
+ AbstractBundle bundle = (AbstractBundle) manager.getBaseData().getBundle();
+ // If the bundle is active, uninstalled or stopping then the bundle has already
+ // been initialized (though it may have been destroyed) so just return the class.
+ if ((bundle.getState() & (Bundle.ACTIVE | Bundle.UNINSTALLED | Bundle.STOPPING)) != 0)
+ return;
+
+ // The bundle is not active and does not require activation, just return the class
+ if (!shouldActivateFor(name, manager.getBaseData()))
+ return;
+
+ // The bundle is starting. Note that if the state changed between the tests
+ // above and this test (e.g., it was not ACTIVE but now is), that's ok, we will
+ // just try to start it again (else case).
+ // TODO need an explanation here of why we duplicated the mechanism
+ // from the framework rather than just calling start() and letting it sort it out.
+ if (bundle.getState() == Bundle.STARTING) {
+ // If the thread trying to load the class is the one trying to activate the bundle, then return the class
+ if (bundle.testStateChanging(Thread.currentThread()) || bundle.testStateChanging(null))
+ return;
+
+ // If it's another thread, we wait and try again. In any case the class is returned.
+ // The difference is that an exception can be logged.
+ // TODO do we really need this test? We just did it on the previous line?
+ if (!bundle.testStateChanging(Thread.currentThread())) {
+ Thread threadChangingState = bundle.getStateChanging();
+ if (StatsManager.TRACE_BUNDLES && threadChangingState != null)
+ System.out.println("Concurrent startup of bundle " + bundle.getSymbolicName() + " by " + Thread.currentThread() + " and " + threadChangingState.getName() + ". Waiting up to 5000ms for " + threadChangingState + " to finish the initialization."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ long start = System.currentTimeMillis();
+ long delay = 5000;
+ long timeLeft = delay;
+ while (true) {
+ try {
+ Thread.sleep(100); // do not release the classloader lock (bug 86713)
+ if (bundle.testStateChanging(null) || timeLeft <= 0)
+ break;
+ } catch (InterruptedException e) {
+ //Ignore and keep waiting
+ }
+ timeLeft = start + delay - System.currentTimeMillis();
+ }
+ if (timeLeft <= 0 || bundle.getState() != Bundle.ACTIVE) {
+ String bundleName = bundle.getSymbolicName() == null ? Long.toString(bundle.getBundleId()) : bundle.getSymbolicName();
+ String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_CONCURRENT_STARTUP, new Object[] {Thread.currentThread().getName(), name, threadChangingState.getName(), bundleName, Long.toString(delay)});
+ manager.getBaseData().getAdaptor().getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, new Exception(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_GENERATED_EXCEPTION), null));
+ }
+ return;
+ }
+ }
+
+ //The bundle must be started.
+ try {
+ bundle.start();
+ } catch (BundleException e) {
+ String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_ACTIVATION, bundle.getSymbolicName(), Long.toString(bundle.getBundleId()));
+ manager.getBaseData().getAdaptor().getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, e, null));
+ throw new ClassNotFoundException(name, e);
+ }
+ return;
+ }
+
+ public void postFindLocalClass(String name, Class clazz, ClasspathManager manager) {
+ // do nothing
+ }
+
+ public void preFindLocalResource(String name, ClasspathManager manager) {
+ // do nothing
+ }
+
+ public void postFindLocalResource(String name, URL resource, ClasspathManager manager) {
+ // do nothing
+ }
+
+ public void recordClassDefine(String name, Class clazz, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
+ // do nothing
+ }
+
+ private boolean shouldActivateFor(String className, BaseData bundledata) throws ClassNotFoundException {
+ if (!isAutoStartable(className, bundledata))
+ return false;
+ //Don't reactivate on shut down
+ if (bundledata.getAdaptor().isStopping()) {
+ BundleStopper stopper = getBundleStopper(bundledata);
+ if (stopper != null && stopper.isStopped(bundledata.getBundle())) {
+ String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_ALREADY_STOPPED, className, bundledata.getSymbolicName());
+ throw new ClassNotFoundException(message);
+ }
+ }
+ return true;
+ }
+
+ private boolean isAutoStartable(String className, BaseData bundledata) {
+ EclipseStorageHook storageHook = (EclipseStorageHook) bundledata.getStorageHook(EclipseStorageHook.KEY);
+ if (storageHook == null)
+ return false;
+ boolean autoStart = storageHook.isAutoStart();
+ String[] autoStartExceptions = storageHook.getAutoStartExceptions();
+ // no exceptions, it is easy to figure it out
+ if (autoStartExceptions == null)
+ return autoStart;
+ // otherwise, we need to check if the package is in the exceptions list
+ int dotPosition = className.lastIndexOf('.');
+ // the class has no package name... no exceptions apply
+ if (dotPosition == -1)
+ return autoStart;
+ String packageName = className.substring(0, dotPosition);
+ // should activate if autoStart and package is not an exception, or if !autoStart and package is exception
+ return autoStart ^ contains(autoStartExceptions, packageName);
+ }
+
+ private boolean contains(String[] array, String element) {
+ for (int i = 0; i < array.length; i++)
+ if (array[i].equals(element))
+ return true;
+ return false;
+ }
+
+ private BundleStopper getBundleStopper(BaseData bundledata) {
+ AdaptorHook[] adaptorhooks = bundledata.getAdaptor().getHookRegistry().getAdaptorHooks();
+ for (int i = 0; i < adaptorhooks.length; i++)
+ if (adaptorhooks[i] instanceof EclipseAdaptorHook)
+ return ((EclipseAdaptorHook) adaptorhooks[i]).getBundleStopper();
+ return null;
+ }
+
+ public void addHooks(HookRegistry hookRegistry) {
+ hookRegistry.addClassLoadingStatsHook(this);
+ }
+}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLogHook.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLogHook.java
new file mode 100644
index 000000000..706db139a
--- /dev/null
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLogHook.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.core.runtime.internal.adaptor;
+
+import java.io.*;
+import java.net.URLConnection;
+import java.util.*;
+import org.eclipse.core.runtime.adaptor.*;
+import org.eclipse.osgi.baseadaptor.*;
+import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
+import org.eclipse.osgi.framework.log.FrameworkLog;
+import org.eclipse.osgi.internal.baseadaptor.AdaptorUtil;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+
+public class EclipseLogHook implements HookConfigurator, AdaptorHook {
+ // The eclipse log file extension */
+ private static final String LOG_EXT = ".log"; //$NON-NLS-1$
+ BaseAdaptor adaptor;
+
+ public void addHooks(HookRegistry hookRegistry) {
+ hookRegistry.addAdaptorHook(this);
+ }
+
+ public void initialize(BaseAdaptor adaptor) {
+ this.adaptor = adaptor;
+ }
+
+ public void frameworkStart(BundleContext context) throws BundleException {
+ AdaptorUtil.register(FrameworkLog.class.getName(), adaptor.getFrameworkLog(), context);
+ registerPerformanceLog(context);
+ }
+
+ public void frameworkStop(BundleContext context) throws BundleException {
+ // TODO should unregister service registered a frameworkStart
+ }
+
+ public void frameworkStopping(BundleContext context) {
+ // do nothing
+
+ }
+
+ public void addProperties(Properties properties) {
+ // do nothing
+ }
+
+ public URLConnection mapLocationToURLConnection(String location) throws IOException {
+ // do nothing
+ return null;
+ }
+
+ public void handleRuntimeError(Throwable error) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public boolean matchDNChain(String pattern, String[] dnChain) {
+ // do nothing
+ return false;
+ }
+
+ public FrameworkLog createFrameworkLog() {
+ FrameworkLog frameworkLog;
+ String logFileProp = FrameworkProperties.getProperty(EclipseStarter.PROP_LOGFILE);
+ if (logFileProp != null) {
+ frameworkLog = new EclipseLog(new File(logFileProp));
+ } else {
+ Location location = LocationManager.getConfigurationLocation();
+ File configAreaDirectory = null;
+ if (location != null)
+ // TODO assumes the URL is a file: url
+ configAreaDirectory = new File(location.getURL().getFile());
+
+ if (configAreaDirectory != null) {
+ String logFileName = Long.toString(System.currentTimeMillis()) + EclipseLogHook.LOG_EXT;
+ File logFile = new File(configAreaDirectory, logFileName);
+ FrameworkProperties.setProperty(EclipseStarter.PROP_LOGFILE, logFile.getAbsolutePath());
+ frameworkLog = new EclipseLog(logFile);
+ } else
+ frameworkLog = new EclipseLog();
+ }
+ if ("true".equals(FrameworkProperties.getProperty(EclipseStarter.PROP_CONSOLE_LOG))) //$NON-NLS-1$
+ frameworkLog.setConsoleLog(true);
+ return frameworkLog;
+ }
+
+ private void registerPerformanceLog(BundleContext context) {
+ Object service = createPerformanceLog();
+ String serviceName = FrameworkLog.class.getName();
+ Hashtable serviceProperties = new Hashtable(7);
+ Dictionary headers = context.getBundle().getHeaders();
+
+ serviceProperties.put(Constants.SERVICE_VENDOR, headers.get(Constants.BUNDLE_VENDOR));
+ serviceProperties.put(Constants.SERVICE_RANKING, new Integer(Integer.MIN_VALUE));
+ serviceProperties.put(Constants.SERVICE_PID, context.getBundle().getBundleId() + '.' + service.getClass().getName());
+ serviceProperties.put(FrameworkLog.SERVICE_PERFORMANCE, Boolean.TRUE.toString());
+
+ context.registerService(serviceName, service, serviceProperties);
+ }
+
+ private FrameworkLog createPerformanceLog() {
+ String logFileProp = FrameworkProperties.getProperty(EclipseStarter.PROP_LOGFILE);
+ if (logFileProp != null) {
+ int lastSlash = logFileProp.lastIndexOf(File.separatorChar);
+ if (lastSlash > 0) {
+ String logFile = logFileProp.substring(0, lastSlash + 1) + "performance.log"; //$NON-NLS-1$
+ return new EclipseLog(new File(logFile));
+ }
+ }
+ //if all else fails, write to std err
+ return new EclipseLog(new PrintWriter(System.err));
+ }
+}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseStorageHook.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseStorageHook.java
new file mode 100644
index 000000000..e619b67ea
--- /dev/null
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseStorageHook.java
@@ -0,0 +1,406 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.core.runtime.internal.adaptor;
+
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+import org.eclipse.core.runtime.adaptor.LocationManager;
+import org.eclipse.osgi.baseadaptor.*;
+import org.eclipse.osgi.baseadaptor.hooks.StorageHook;
+import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
+import org.eclipse.osgi.framework.log.FrameworkLogEntry;
+import org.eclipse.osgi.framework.util.Headers;
+import org.eclipse.osgi.framework.util.KeyedElement;
+import org.eclipse.osgi.internal.baseadaptor.AdaptorUtil;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.eclipse.osgi.service.pluginconversion.PluginConversionException;
+import org.eclipse.osgi.util.ManifestElement;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Version;
+
+public final class EclipseStorageHook implements StorageHook, HookConfigurator {
+ // System property used to check timestamps of the bundles in the configuration
+ private static final String PROP_CHECK_CONFIG = "osgi.checkConfiguration"; //$NON-NLS-1$
+ private static final int STORAGE_VERION = 1;
+
+ public static final String KEY = EclipseStorageHook.class.getName();
+ public static final int HASHCODE = KEY.hashCode();
+
+ /** data to detect modification made in the manifest */
+ private long manifestTimeStamp = 0;
+ private byte manifestType = PluginConverterImpl.MANIFEST_TYPE_UNKNOWN;
+
+ private BaseData bundledata;
+
+ /** the Plugin-Class header */
+ private String pluginClass = null;
+ /** Eclipse-LazyStart header */
+ private boolean autoStart;
+ private String[] autoStartExceptions;
+ /** shortcut to know if a bundle has a buddy */
+ private String buddyList;
+ /** shortcut to know if a bundle is a registrant to a registered policy */
+ private String registeredBuddyList;
+ /** shortcut to know if the bundle manifest has package info */
+ private boolean hasPackageInfo;
+
+ public int getStorageVersion() {
+ return STORAGE_VERION;
+ }
+
+ public StorageHook create(BaseData bundledata) throws BundleException {
+ EclipseStorageHook storageHook = new EclipseStorageHook();
+ storageHook.bundledata = bundledata;
+ return storageHook;
+ }
+
+ public void initialize(Dictionary manifest) throws BundleException {
+ String lazyStart = (String) manifest.get(Constants.ECLIPSE_LAZYSTART);
+ if (lazyStart == null)
+ lazyStart = (String) manifest.get(Constants.ECLIPSE_AUTOSTART);
+ parseLazyStart(this, lazyStart);
+ pluginClass = (String) manifest.get(Constants.PLUGIN_CLASS);
+ buddyList = (String) manifest.get(Constants.BUDDY_LOADER);
+ registeredBuddyList = (String) manifest.get(Constants.REGISTERED_POLICY);
+ hasPackageInfo = hasPackageInfo(bundledata.getEntry(Constants.OSGI_BUNDLE_MANIFEST));
+ String genFrom = (String) manifest.get(PluginConverterImpl.GENERATED_FROM);
+ if (genFrom != null) {
+ ManifestElement generatedFrom = ManifestElement.parseHeader(PluginConverterImpl.GENERATED_FROM, genFrom)[0];
+ if (generatedFrom != null) {
+ manifestTimeStamp = Long.parseLong(generatedFrom.getValue());
+ manifestType = Byte.parseByte(generatedFrom.getAttribute(PluginConverterImpl.MANIFEST_TYPE_ATTRIBUTE));
+ }
+ }
+ }
+
+ public StorageHook load(BaseData target, DataInputStream in) throws IOException {
+ EclipseStorageHook storageHook = new EclipseStorageHook();
+ storageHook.bundledata = target;
+ storageHook.autoStart = in.readBoolean();
+ int exceptionsCount = in.readInt();
+ storageHook.autoStartExceptions = exceptionsCount > 0 ? new String[exceptionsCount] : null;
+ for (int i = 0; i < exceptionsCount; i++)
+ storageHook.autoStartExceptions[i] = in.readUTF();
+ storageHook.hasPackageInfo = in.readBoolean();
+ storageHook.buddyList = AdaptorUtil.readString(in, false);
+ storageHook.registeredBuddyList = AdaptorUtil.readString(in, false);
+ storageHook.pluginClass = AdaptorUtil.readString(in, false);
+ storageHook.manifestTimeStamp = in.readLong();
+ storageHook.manifestType = in.readByte();
+ return storageHook;
+ }
+
+ public void save(DataOutputStream out) throws IOException {
+ if (bundledata == null)
+ throw new IllegalStateException();
+ out.writeBoolean(isAutoStart());
+ String[] autoStartExceptions = getAutoStartExceptions();
+ if (autoStartExceptions == null)
+ out.writeInt(0);
+ else {
+ out.writeInt(autoStartExceptions.length);
+ for (int i = 0; i < autoStartExceptions.length; i++)
+ out.writeUTF(autoStartExceptions[i]);
+ }
+ out.writeBoolean(hasPackageInfo());
+ AdaptorUtil.writeStringOrNull(out, getBuddyList());
+ AdaptorUtil.writeStringOrNull(out, getRegisteredBuddyList());
+ AdaptorUtil.writeStringOrNull(out, getPluginClass());
+ out.writeLong(getManifestTimeStamp());
+ out.writeByte(getManifestType());
+ }
+
+ public int getKeyHashCode() {
+ return HASHCODE;
+ }
+
+ public boolean compare(KeyedElement other) {
+ return other.getKey() == KEY;
+ }
+
+ public Object getKey() {
+ return KEY;
+ }
+
+ public boolean isAutoStart() {
+ return autoStart;
+ }
+
+ public String[] getAutoStartExceptions() {
+ return autoStartExceptions;
+ }
+
+ public String getBuddyList() {
+ return buddyList;
+ }
+
+ public boolean hasPackageInfo() {
+ return hasPackageInfo;
+ }
+
+ public String getPluginClass() {
+ return pluginClass;
+ }
+
+ public String getRegisteredBuddyList() {
+ return registeredBuddyList;
+ }
+
+ public long getManifestTimeStamp() {
+ return manifestTimeStamp;
+ }
+
+ public byte getManifestType() {
+ return manifestType;
+ }
+
+ /**
+ * Checks whether this bundle is auto started for all resource/class loads or only for a
+ * subset of resource/classloads
+ * @return true if the bundle is auto started; false otherwise
+ */
+ public boolean isAutoStartable() {
+ return autoStart || (autoStartExceptions != null && autoStartExceptions.length > 0);
+ }
+
+ private void parseLazyStart(EclipseStorageHook storageHook, String headerValue) {
+ storageHook.autoStart = false;
+ storageHook.autoStartExceptions = null;
+ ManifestElement[] allElements = null;
+ try {
+ allElements = ManifestElement.parseHeader(Constants.ECLIPSE_LAZYSTART, headerValue);
+ } catch (BundleException e) {
+ // just use the default settings (no auto activation)
+ String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_CANNOT_GET_HEADERS, storageHook.bundledata.getLocation());
+ bundledata.getAdaptor().getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, e, null));
+ }
+ //Eclipse-AutoStart not found...
+ if (allElements == null)
+ return;
+ // the single value for this element should be true|false
+ storageHook.autoStart = "true".equalsIgnoreCase(allElements[0].getValue()); //$NON-NLS-1$
+ // look for any exceptions (the attribute) to the autoActivate setting
+ String exceptionsValue = allElements[0].getAttribute(Constants.ECLIPSE_LAZYSTART_EXCEPTIONS);
+ if (exceptionsValue == null)
+ return;
+ StringTokenizer tokenizer = new StringTokenizer(exceptionsValue, ","); //$NON-NLS-1$
+ int numberOfTokens = tokenizer.countTokens();
+ storageHook.autoStartExceptions = new String[numberOfTokens];
+ for (int i = 0; i < numberOfTokens; i++)
+ storageHook.autoStartExceptions[i] = tokenizer.nextToken().trim();
+ }
+
+ // Used to check the bundle manifest file for any package information.
+ // This is used when '.' is on the Bundle-ClassPath to prevent reading
+ // the bundle manifest for pacakge information when loading classes.
+ private static boolean hasPackageInfo(URL url) {
+ if (url == null)
+ return false;
+ BufferedReader br = null;
+ try {
+ br = new BufferedReader(new InputStreamReader(url.openStream()));
+ String line;
+ while ((line = br.readLine()) != null) {
+ if (line.startsWith("Specification-Title: ") || line.startsWith("Specification-Version: ") || line.startsWith("Specification-Vendor: ") || line.startsWith("Implementation-Title: ") || line.startsWith("Implementation-Version: ") || line.startsWith("Implementation-Vendor: ")) //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+ return true;
+ }
+ } catch (IOException ioe) {
+ // do nothing
+ } finally {
+ if (br != null)
+ try {
+ br.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ return false;
+ }
+
+ public void addHooks(HookRegistry hookRegistry) {
+ hookRegistry.addStorageHook(this);
+ }
+
+ private void checkTimeStamp() throws IllegalArgumentException {
+ if (!checkManifestTimeStamp())
+ throw new IllegalArgumentException();
+ }
+
+ private boolean checkManifestTimeStamp() {
+ if (!"true".equalsIgnoreCase(FrameworkProperties.getProperty(EclipseStorageHook.PROP_CHECK_CONFIG))) //$NON-NLS-1$
+ return true;
+ if (PluginConverterImpl.getTimeStamp(bundledata.getBundleFile().getBaseFile(), getManifestType()) == getManifestTimeStamp()) {
+ if ((getManifestType() & (PluginConverterImpl.MANIFEST_TYPE_JAR | PluginConverterImpl.MANIFEST_TYPE_BUNDLE)) != 0)
+ return true;
+ String cacheLocation = FrameworkProperties.getProperty(LocationManager.PROP_MANIFEST_CACHE);
+ Location parentConfiguration = LocationManager.getConfigurationLocation().getParentLocation();
+ if (parentConfiguration != null) {
+ try {
+ return checkManifestAndParent(cacheLocation, bundledata.getSymbolicName(), bundledata.getVersion().toString(), getManifestType()) != null;
+ } catch (BundleException e) {
+ return false;
+ }
+ }
+ File cacheFile = new File(cacheLocation, bundledata.getSymbolicName() + '_' + bundledata.getVersion() + ".MF"); //$NON-NLS-1$
+ if (cacheFile.isFile())
+ return true;
+ }
+ return false;
+ }
+
+ private Headers checkManifestAndParent(String cacheLocation, String symbolicName, String version, byte inputType) throws BundleException {
+ Headers result = basicCheckManifest(cacheLocation, symbolicName, version, inputType);
+ if (result != null)
+ return result;
+ Location parentConfiguration = null;
+ if ((parentConfiguration = LocationManager.getConfigurationLocation().getParentLocation()) != null)
+ result = basicCheckManifest(new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + '/' + LocationManager.MANIFESTS_DIR).toString(), symbolicName, version, inputType);
+ return result;
+ }
+
+ private Headers basicCheckManifest(String cacheLocation, String symbolicName, String version, byte inputType) throws BundleException {
+ File currentFile = new File(cacheLocation, symbolicName + '_' + version + ".MF"); //$NON-NLS-1$
+ if (PluginConverterImpl.upToDate(currentFile, bundledata.getBundleFile().getBaseFile(), inputType)) {
+ try {
+ return Headers.parseManifest(new FileInputStream(currentFile));
+ } catch (FileNotFoundException e) {
+ // do nothing.
+ }
+ }
+ return null;
+ }
+
+ Dictionary createCachedManifest(boolean firstTime) throws BundleException {
+ return firstTime ? getGeneratedManifest() : new CachedManifest(this);
+ }
+
+ public Dictionary getGeneratedManifest() throws BundleException {
+ Dictionary builtIn = AdaptorUtil.loadManifestFrom(bundledata);
+ if (builtIn != null) {
+ // the bundle has a built-in manifest - we may not have to generate one
+ if (!isComplete(builtIn)) {
+ Dictionary generatedManifest = generateManifest(builtIn);
+ if (generatedManifest != null)
+ return generatedManifest;
+ }
+ // the manifest is complete or we could not complete it - take it as it is
+ manifestType = PluginConverterImpl.MANIFEST_TYPE_BUNDLE;
+ if (bundledata.getBundleFile().getBaseFile().isFile()) {
+ manifestTimeStamp = bundledata.getBundleFile().getBaseFile().lastModified();
+ manifestType |= PluginConverterImpl.MANIFEST_TYPE_JAR;
+ } else
+ manifestTimeStamp = bundledata.getBundleFile().getEntry(Constants.OSGI_BUNDLE_MANIFEST).getTime();
+ return builtIn;
+ }
+ Dictionary result = generateManifest(null);
+ if (result == null)
+ throw new BundleException(NLS.bind(EclipseAdaptorMsg.ECLIPSE_DATA_MANIFEST_NOT_FOUND, bundledata.getLocation()));
+ return result;
+ }
+
+ private Dictionary generateManifest(Dictionary builtIn) throws BundleException {
+ String cacheLocation = FrameworkProperties.getProperty(LocationManager.PROP_MANIFEST_CACHE);
+ if (bundledata.getSymbolicName() != null) {
+ Headers existingHeaders = checkManifestAndParent(cacheLocation, bundledata.getSymbolicName(), bundledata.getVersion().toString(), manifestType);
+ if (existingHeaders != null)
+ return existingHeaders;
+ }
+
+ PluginConverterImpl converter = PluginConverterImpl.getDefault();
+ if (converter == null)
+ converter = new PluginConverterImpl(bundledata.getAdaptor(), bundledata.getAdaptor().getContext());
+
+ Dictionary generatedManifest;
+ try {
+ generatedManifest = converter.convertManifest(bundledata.getBundleFile().getBaseFile(), true, null, true, null);
+ } catch (PluginConversionException pce) {
+ String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_ERROR_CONVERTING, bundledata.getBundleFile().getBaseFile());
+ throw new BundleException(message, pce);
+ }
+
+ //Now we know the symbolicId and the version of the bundle, we check to see if don't have a manifest for it already
+ Version version = Version.parseVersion((String) generatedManifest.get(Constants.BUNDLE_VERSION));
+ String symbolicName = ManifestElement.parseHeader(org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME, (String) generatedManifest.get(org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME))[0].getValue();
+ ManifestElement generatedFrom = ManifestElement.parseHeader(PluginConverterImpl.GENERATED_FROM, (String) generatedManifest.get(PluginConverterImpl.GENERATED_FROM))[0];
+ Headers existingHeaders = checkManifestAndParent(cacheLocation, symbolicName, version.toString(), Byte.parseByte(generatedFrom.getAttribute(PluginConverterImpl.MANIFEST_TYPE_ATTRIBUTE)));
+ //We don't have a manifest.
+ manifestTimeStamp = Long.parseLong(generatedFrom.getValue());
+ manifestType = Byte.parseByte(generatedFrom.getAttribute(PluginConverterImpl.MANIFEST_TYPE_ATTRIBUTE));
+ if (bundledata.getAdaptor().isReadOnly() || existingHeaders != null)
+ return existingHeaders;
+
+ //merge the original manifest with the generated one
+ if (builtIn != null) {
+ Enumeration keysEnum = builtIn.keys();
+ while (keysEnum.hasMoreElements()) {
+ Object key = keysEnum.nextElement();
+ generatedManifest.put(key, builtIn.get(key));
+ }
+ }
+
+ //write the generated manifest
+ File bundleManifestLocation = new File(cacheLocation, symbolicName + '_' + version.toString() + ".MF"); //$NON-NLS-1$
+ try {
+ converter.writeManifest(bundleManifestLocation, generatedManifest, true);
+ } catch (Exception e) {
+ //TODO Need to log
+ }
+ return generatedManifest;
+
+ }
+
+ private boolean isComplete(Dictionary manifest) {
+ // a manifest is complete if it has a Bundle-SymbolicName entry...
+ if (manifest.get(org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME) != null)
+ return true;
+ // ...or it does not have a plugin/fragment manifest where to get the other entries from
+ return bundledata.getEntry(PluginConverterImpl.PLUGIN_MANIFEST) == null && bundledata.getEntry(PluginConverterImpl.FRAGMENT_MANIFEST) == null;
+ }
+
+ public BaseData getBaseData() {
+ return bundledata;
+ }
+
+ public void copy(StorageHook storageHook) {
+ // copy nothing all must be re-read from a manifest
+ }
+
+ public void validate() throws IllegalArgumentException {
+ checkTimeStamp();
+ }
+
+ public FrameworkAdaptor getAdaptor() {
+ if (bundledata != null)
+ return bundledata.getAdaptor();
+ return null;
+ }
+
+ public Dictionary getManifest(boolean firstLoad) throws BundleException {
+ return createCachedManifest(firstLoad);
+ }
+
+ public boolean forgetStatusChange(int status) {
+ return isAutoStartable();
+ }
+
+ public boolean forgetStartLevelChange(int startlevel) {
+ return false;
+ }
+
+ public boolean matchDNChain(String pattern) {
+ return false;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/Locker_JavaNio.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/Locker_JavaNio.java
index ee8ce4914..6b7ed956b 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/Locker_JavaNio.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/Locker_JavaNio.java
@@ -12,7 +12,6 @@ package org.eclipse.core.runtime.internal.adaptor;
import java.io.*;
import java.nio.channels.FileLock;
-import org.eclipse.core.runtime.adaptor.EclipseAdaptorMsg;
import org.eclipse.osgi.util.NLS;
/**
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/PluginConverterImpl.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/PluginConverterImpl.java
index 767c06262..37200679d 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/PluginConverterImpl.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/PluginConverterImpl.java
@@ -18,10 +18,10 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.eclipse.core.runtime.adaptor.*;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
-import org.eclipse.osgi.framework.adaptor.core.DevClassPathHelper;
import org.eclipse.osgi.framework.internal.core.Constants;
import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
+import org.eclipse.osgi.internal.baseadaptor.DevClassPathHelper;
import org.eclipse.osgi.service.pluginconversion.PluginConversionException;
import org.eclipse.osgi.service.pluginconversion.PluginConverter;
import org.eclipse.osgi.service.resolver.VersionRange;
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/PluginParser.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/PluginParser.java
index f509a13c3..038eaf067 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/PluginParser.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/PluginParser.java
@@ -13,7 +13,6 @@ package org.eclipse.core.runtime.internal.adaptor;
import java.io.InputStream;
import java.util.*;
import javax.xml.parsers.SAXParserFactory;
-import org.eclipse.core.runtime.adaptor.EclipseAdaptorMsg;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.util.NLS;
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/stats/StatsManager.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/stats/StatsManager.java
index 5cb19f03f..998d2488b 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/stats/StatsManager.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/stats/StatsManager.java
@@ -11,14 +11,22 @@
package org.eclipse.core.runtime.internal.stats;
import java.io.*;
+import java.net.URL;
import java.util.*;
+import org.eclipse.osgi.baseadaptor.HookConfigurator;
+import org.eclipse.osgi.baseadaptor.HookRegistry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingStatsHook;
+import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry;
+import org.eclipse.osgi.baseadaptor.loader.ClasspathManager;
import org.eclipse.osgi.framework.adaptor.BundleWatcher;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
+import org.eclipse.osgi.framework.debug.Debug;
import org.eclipse.osgi.framework.debug.FrameworkDebugOptions;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.Bundle;
-public class StatsManager implements BundleWatcher {
+public class StatsManager implements BundleWatcher, HookConfigurator, ClassLoadingStatsHook {
// This connect bundles and their info, and so allows to access the info without running through
// the bundle registry. This map only contains activated bundles. The key is the bundle Id
private Hashtable bundles = new Hashtable(20);
@@ -97,6 +105,17 @@ public class StatsManager implements BundleWatcher {
bundle.setDuringStartup(booting);
}
+ public void watchBundle(Bundle bundle, int type) {
+ switch (type) {
+ case BundleWatcher.START_ACTIVATION :
+ startActivation(bundle);
+ break;
+ case BundleWatcher.END_ACTIVATION :
+ endActivation(bundle);
+ break;
+ }
+ }
+
public void startActivation(Bundle bundle) {
// should be called from a synchronized location to protect against concurrent updates
BundleStats info = findBundle(bundle.getSymbolicName(), bundle.getBundleId());
@@ -177,4 +196,39 @@ public class StatsManager implements BundleWatcher {
return (BundleStats) bundles.get(new Long(id));
}
+ public void preFindLocalClass(String name, ClasspathManager manager) throws ClassNotFoundException {
+ if (StatsManager.MONITOR_CLASSES) //Support for performance analysis
+ ClassloaderStats.startLoadingClass(getClassloaderId(manager), name);
+ }
+
+ public void postFindLocalClass(String name, Class clazz, ClasspathManager manager) {
+ if (StatsManager.MONITOR_CLASSES)
+ ClassloaderStats.endLoadingClass(getClassloaderId(manager), name, clazz != null);
+ }
+
+ public void preFindLocalResource(String name, ClasspathManager manager) {
+ // do nothing
+ }
+
+ public void postFindLocalResource(String name, URL resource, ClasspathManager manager) {
+ if (StatsManager.MONITOR_RESOURCES)
+ if (resource != null && name.endsWith(".properties")) //$NON-NLS-1$
+ ClassloaderStats.loadedBundle(getClassloaderId(manager), new ResourceBundleStats(getClassloaderId(manager), name, resource));
+ return;
+ }
+
+ public void recordClassDefine(String name, Class clazz, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
+ // do nothing
+ }
+
+ private String getClassloaderId(ClasspathManager loader) {
+ return loader.getBaseData().getSymbolicName();
+ }
+
+ public void addHooks(HookRegistry hookRegistry) {
+ if (Debug.MONITOR_ACTIVATION)
+ hookRegistry.addWatcher(StatsManager.getDefault());
+ if (StatsManager.MONITOR_CLASSES || StatsManager.MONITOR_RESOURCES)
+ hookRegistry.addClassLoadingStatsHook(StatsManager.getDefault());
+ }
}
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/service/datalocation/Location.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/service/datalocation/Location.java
index b8fba576e..6b1ebe3a9 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/service/datalocation/Location.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/service/datalocation/Location.java
@@ -128,6 +128,7 @@ public interface Location {
* Locking a location is advisory only. That is, it does not prevent other applications from
* modifying the same location
* </p>
+ * @return true if the lock could be acquired; otherwise false is returned
*
* @exception IOException if there was an unexpected problem while acquiring the lock
*/
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/service/localization/BundleLocalization.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/service/localization/BundleLocalization.java
index 7e4fa4586..2061517ba 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/service/localization/BundleLocalization.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/service/localization/BundleLocalization.java
@@ -26,6 +26,8 @@ public interface BundleLocalization {
/**
* The getLocalization method gets a ResourceBundle object for the given
* locale and bundle.
+ * @param bundle the bundle to get localization for
+ * @param locale the name of the locale to get
*
* @return A <code>ResourceBundle</code> object for the given bundle and locale.
* If <code>null</code> is passed for the locale parameter, the default locale is used.
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/storagemanager/ManagedOutputStream.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/storagemanager/ManagedOutputStream.java
index 7a3aaaf0c..4c4cf045d 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/storagemanager/ManagedOutputStream.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/storagemanager/ManagedOutputStream.java
@@ -46,6 +46,7 @@ public final class ManagedOutputStream extends FilterOutputStream {
* a set returned by {@link StorageManager#getOutputStreamSet(String[])} then
* the storage manager will only be updated with the new content after all
* of the managed output streams in the set are closed successfully.
+ * @see FilterOutputStream#close()
*/
public void close() throws IOException {
manager.closeOutputStream(this);
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/storagemanager/StorageManager.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/storagemanager/StorageManager.java
index 1ab2e7901..09f973563 100644
--- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/storagemanager/StorageManager.java
+++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/osgi/storagemanager/StorageManager.java
@@ -12,9 +12,7 @@ package org.eclipse.osgi.storagemanager;
import java.io.*;
import java.util.*;
-import org.eclipse.core.runtime.adaptor.EclipseAdaptorMsg;
-import org.eclipse.core.runtime.internal.adaptor.BasicLocation;
-import org.eclipse.core.runtime.internal.adaptor.Locker;
+import org.eclipse.core.runtime.internal.adaptor.*;
import org.eclipse.osgi.framework.internal.reliablefile.*;
import org.eclipse.osgi.framework.util.SecureAction;
@@ -459,6 +457,7 @@ public final class StorageManager {
* Removes the given managed file from management by this storage manager.
*
* @param managedFile the managed file to remove
+ * @throws IOException if an error occured removing the managed file
*/
public void remove(String managedFile) throws IOException {
if (!open)
@@ -686,6 +685,7 @@ public final class StorageManager {
* This methods opens the storage manager.
* This method must be called before any operation on the storage manager.
* @param wait indicates if the open operation must wait in case of contention on the lock file.
+ * @throws IOException if an error occured opening the storage manager
*/
public void open(boolean wait) throws IOException {
if (openCleanup)
diff --git a/bundles/org.eclipse.osgi/hookconfigurators.properties b/bundles/org.eclipse.osgi/hookconfigurators.properties
new file mode 100644
index 000000000..b01d3377f
--- /dev/null
+++ b/bundles/org.eclipse.osgi/hookconfigurators.properties
@@ -0,0 +1,20 @@
+###############################################################################
+# Copyright (c) 2005, 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+hook.configurators= \
+ org.eclipse.osgi.internal.baseadaptor.BaseHookConfigurator,\
+ org.eclipse.osgi.internal.baseadaptor.DevClassLoadingHook,\
+ org.eclipse.core.runtime.internal.adaptor.EclipseStorageHook,\
+ org.eclipse.core.runtime.internal.adaptor.EclipseLogHook,\
+ org.eclipse.core.runtime.internal.adaptor.EclipseErrorHandler,\
+ org.eclipse.core.runtime.internal.adaptor.EclipseAdaptorHook,\
+ org.eclipse.core.runtime.internal.adaptor.EclipseClassLoadingHook,\
+ org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter,\
+ org.eclipse.core.runtime.internal.stats.StatsManager
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java
index 536f34bc2..b8c75671c 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java
@@ -13,7 +13,7 @@ package org.eclipse.osgi.internal.resolver;
import java.io.IOException;
import java.util.*;
import org.eclipse.osgi.framework.internal.core.Constants;
-import org.eclipse.osgi.framework.internal.core.KeyedElement;
+import org.eclipse.osgi.framework.util.KeyedElement;
import org.eclipse.osgi.service.resolver.*;
public class BundleDescriptionImpl extends BaseDescriptionImpl implements BundleDescription, KeyedElement {
@@ -323,13 +323,15 @@ public class BundleDescriptionImpl extends BaseDescriptionImpl implements Bundle
}
protected synchronized void addDependency(BaseDescriptionImpl dependency) {
- if (dependencies == null)
- dependencies = new ArrayList(10);
BundleDescriptionImpl bundle;
if (dependency instanceof ExportPackageDescription)
bundle = (BundleDescriptionImpl) ((ExportPackageDescription) dependency).getExporter();
else
bundle = (BundleDescriptionImpl) dependency;
+ if (bundle == this)
+ return;
+ if (dependencies == null)
+ dependencies = new ArrayList(10);
if (!dependencies.contains(bundle)) {
bundle.addDependent(this);
dependencies.add(bundle);
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateDeltaImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateDeltaImpl.java
index 5e930434c..4ddaabed0 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateDeltaImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateDeltaImpl.java
@@ -86,7 +86,6 @@ public class StateDeltaImpl implements StateDelta {
}
void recordBundleRemovalPending(BundleDescriptionImpl removed) {
- removed.setStateBit(BundleDescriptionImpl.REMOVAL_PENDING, true);
BundleDeltaImpl change = (BundleDeltaImpl) changes.get(removed);
if (change == null) {
changes.put(removed, new BundleDeltaImpl(removed, BundleDelta.REMOVAL_PENDING));
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java
index d5a7f59c2..c4c2186ba 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java
@@ -12,10 +12,12 @@ package org.eclipse.osgi.internal.resolver;
import java.util.*;
-import org.eclipse.osgi.framework.adaptor.core.StateManager;
import org.eclipse.osgi.framework.debug.Debug;
import org.eclipse.osgi.framework.debug.FrameworkDebugOptions;
import org.eclipse.osgi.framework.internal.core.*;
+import org.eclipse.osgi.framework.util.KeyedElement;
+import org.eclipse.osgi.framework.util.KeyedHashSet;
+import org.eclipse.osgi.internal.baseadaptor.StateManager;
import org.eclipse.osgi.service.resolver.*;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.BundleException;
@@ -64,6 +66,7 @@ public abstract class StateImpl implements State {
if (!bundleDescriptions.remove(existing))
return false;
resolvedBundles.remove(existing);
+ existing.setStateBit(BundleDescriptionImpl.REMOVAL_PENDING, true);
if (!basicAddBundle(newDescription))
return false;
resolved = false;
@@ -105,6 +108,7 @@ public abstract class StateImpl implements State {
resolvedBundles.remove((KeyedElement) toRemove);
resolved = false;
getDelta().recordBundleRemoved((BundleDescriptionImpl) toRemove);
+ ((BundleDescriptionImpl) toRemove).setStateBit(BundleDescriptionImpl.REMOVAL_PENDING, true);
if (resolver != null) {
boolean pending = toRemove.getDependents().length > 0;
resolver.bundleRemoved(toRemove, pending);
@@ -385,6 +389,7 @@ public abstract class StateImpl implements State {
boolean basicAddBundle(BundleDescription description) {
((BundleDescriptionImpl) description).setContainingState(this);
+ ((BundleDescriptionImpl) description).setStateBit(BundleDescriptionImpl.REMOVAL_PENDING, false);
return bundleDescriptions.add((BundleDescriptionImpl) description);
}
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMessages.properties b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMessages.properties
new file mode 100644
index 000000000..a9887e71e
--- /dev/null
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMessages.properties
@@ -0,0 +1,105 @@
+###############################################################################
+# Copyright (c) 2004 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+
+#External Messages for EN locale
+
+#EclipseAdaptor messages
+ECLIPSE_ADAPTOR_ERROR_XML_SERVICE=Error registering XML parser services.
+ECLIPSE_ADAPTOR_RUNTIME_ERROR=An unexpected runtime error has occurred.
+ECLIPSE_ADAPTOR_EXITING=The application will terminate.
+
+#EclipseStarter messages
+ECLIPSE_STARTUP_BUNDLE_NOT_FOUND=Bundle {0} not found.
+ECLIPSE_STARTUP_ROOTS_NOT_RESOLVED=One or more bundles are not resolved because the following root constraints are not resolved:
+ECLIPSE_STARTUP_ALL_NOT_RESOLVED=The following is a complete list of bundles which are not resolved, see the prior log entry for the root cause if it exists:
+ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_RESOLVED=Bundle {0} was not resolved.
+ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_ACTIVE=Bundle {0} is not active.
+ECLIPSE_STARTUP_ERROR_NO_APPLICATION=Unable to acquire application service.
+#Don't use double quotes in the ECLIPSE_STARTUP_ERROR_CHECK_LOG. (See bug 86085)
+ECLIPSE_STARTUP_ERROR_CHECK_LOG=An error has occurred. See the log file\n{0}.
+ECLIPSE_STARTUP_ALREADY_RUNNING=Platform already running
+ECLIPSE_STARTUP_NOT_RUNNING=Platform not running
+ECLIPSE_STARTUP_STARTUP_ERROR=Startup error
+ECLIPSE_STARTUP_APP_ERROR=Application error
+ECLIPSE_STARTUP_SHUTDOWN_ERROR=Shutdown error
+ECLIPSE_STARTUP_INVALID_PORT=Invalid console port: {0}
+ECLIPSE_STARTUP_FAILED_FIND=Failed to find/start: {0}
+ECLIPSE_STARTUP_FAILED_INSTALL=Error installing bundle: {0}
+ECLIPSE_STARTUP_FAILED_UNINSTALL=Error uninstalling bundle: {0}
+ECLIPSE_STARTUP_FAILED_START=Error starting bundle: {0}
+ECLIPSE_STARTUP_FILEMANAGER_OPEN_ERROR=Error reading configuration: {0}
+ECLIPSE_STARTUP_PROPS_NOT_SET=Cannot start without the following system properties set: {0}
+
+#EclipseBundleData messages
+ECLIPSE_DATA_MANIFEST_NOT_FOUND=Manifest not found: {0}
+ECLIPSE_DATA_ERROR_READING_MANIFEST=Error reading manifest for bundle at the location: {0}
+
+#Console extension
+ECLIPSE_CONSOLE_NO_BUNDLE_SPECIFIED_ERROR=No bundle specified!.
+ECLIPSE_CONSOLE_CANNOT_FIND_BUNDLE_ERROR=Cannot find bundle {0}.
+ECLIPSE_CONSOLE_NO_CONSTRAINTS_NO_PLATFORM_ADMIN_MESSAGE=No unresolved constraints [PlatformAdmin service is not registered].
+ECLIPSE_CONSOLE_NO_CONSTRAINTS=No unresolved constraints.
+ECLIPSE_CONSOLE_OTHER_VERSION=Bundle {0} was picked instead.
+ECLIPSE_CONSOLE_COMMANDS_HEADER=Eclipse Runtime commands.
+ECLIPSE_CONSOLE_HELP_DIAG_COMMAND_DESCRIPTION=Displays unsatisfied constraints for the specified bundle(s).
+ECLIPSE_CONSOLE_HELP_ACTIVE_COMMAND_DESCRIPTION=Displays a list of all bundles currently in the ACTIVE state.
+ECLIPSE_CONSOLE_HELP_GETPROP_COMMAND_DESCRIPTION={ name } - Displays the system properties with the given name, or all of them.
+ECLIPSE_CONSOLE_BUNDLES_ACTIVE={0} active bundle(s).
+
+#Bundle resolution messages
+ECLIPSE_MISSING_OPTIONAL_REQUIRED_BUNDLE=Missing optionally required bundle {0}.
+ECLIPSE_MISSING_REQUIRED_BUNDLE=Missing required bundle {0}.
+ECLIPSE_MISSING_IMPORTED_PACKAGE=Missing imported package {0}.
+ECLIPSE_MISSING_HOST=Missing host {0}.
+
+#Conversion messages
+ECLIPSE_CONVERTER_ERROR_CONVERTING=Error converting plugin at {0}.
+ECLIPSE_CONVERTER_ERROR_CREATING_BUNDLE_MANIFEST=Error creating bundle manifest file for {0} at {1}.
+ECLIPSE_CONVERTER_ERROR_PARSING_PLUGIN_MANIFEST=Error parsing plugin manifest file {0} at {1}.
+ECLIPSE_CONVERTER_MISSING_ATTRIBUTE=Error parsing {0} manifest. Missing attribute \"{1}\" in element \"{2}\".
+ECLIPSE_CONVERTER_PLUGIN_LIBRARY_IGNORED=Plugin library {0} ignored when creating manifest for {1}.
+ECLIPSE_CONVERTER_NO_SAX_FACTORY=No SAX factory parser has been found.
+ECLIPSE_CONVERTER_PARSE_UNKNOWNTOP_ELEMENT = Unknown element \"{0}\", found at the top level, ignored.
+ECLIPSE_CONVERTER_FILENOTFOUND = Could not find a plugin.xml or a fragment.xml in {0}.
+parse_error=Error parsing manifest: {0}
+parse_errorNameLineColumn=Error parsing manifest at \"{0}\" line \"{1}\" column \"{2}\": {3}
+
+#Classloader messages
+ECLIPSE_CLASSLOADER_CANNOT_GET_HEADERS=Error loading bundle manifest for {0}. Using default auto-activation settings.
+ECLIPSE_CLASSLOADER_CONCURRENT_STARTUP=While loading class "{1}", thread "{0}" timed out waiting ({4}ms) for thread "{2}" to finish starting bundle "{3}". To avoid deadlock, thread "{0}" is proceeding but "{1}" may not be fully initialized.
+ECLIPSE_CLASSLOADER_ACTIVATION=An error occurred while automatically activating bundle {0} ({1}).
+ECLIPSE_CLASSLOADER_GENERATED_EXCEPTION=Generated exception.
+ECLIPSE_CLASSLOADER_ALREADY_STOPPED= The class \"{0}\" cannot be loaded because the system is shutting down and the plug-in \"{1}\" has already been stopped.
+ECLIPSE_CLASSLOADER_CANNOT_SET_CONTEXTFINDER=The context finder has not been installed.
+
+#CachedManifest messages
+ECLIPSE_CACHEDMANIFEST_UNEXPECTED_EXCEPTION=Unexpected exception occurred loading manifest for bundle at the location: {0}.
+
+#BundleStopper messages
+ECLIPSE_BUNDLESTOPPER_CYCLES_FOUND=Info: cycle(s) found while stopping bundles: {0}.
+ECLIPSE_BUNDLESTOPPER_ERROR_STOPPING_BUNDLE=Error while stopping \"{0}\".
+
+#Location message
+ECLIPSE_CANNOT_CHANGE_LOCATION = Cannot change the location once it is set.
+
+#NL Problem
+error_badNL=Bad value: \"{0}\" for NL. Using system default.
+
+#FileMananger messages
+fileManager_cannotLock = Unable to create lock manager.
+fileManager_couldNotSave = Could not save file table.
+fileManager_updateFailed = File update failed on one or more files.
+fileManager_illegalInReadOnlyMode = Cannot perform operation while in read-only mode.
+fileManager_notOpen = Manager is not opened.
+
+#Location messages
+location_cannotLockNIO = An error occurred while locking file \"{0}\": \"{1}\". A common reason is that the file system or Runtime Environment does not support file locking for that location. Please choose a different location, or disable file locking passing {2} as a VM argument.
+location_cannotLock = An error occurred while locking file \"{0}\".
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMsg.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMsg.java
new file mode 100644
index 000000000..1c2db825a
--- /dev/null
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/EclipseAdaptorMsg.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.core.runtime.internal.adaptor;
+
+import java.util.Date;
+import org.eclipse.osgi.service.resolver.*;
+import org.eclipse.osgi.util.NLS;
+
+public class EclipseAdaptorMsg extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.core.runtime.internal.adaptor.EclipseAdaptorMessages"; //$NON-NLS-1$
+
+ public static String ECLIPSE_MISSING_IMPORTED_PACKAGE;
+ public static String ECLIPSE_MISSING_OPTIONAL_REQUIRED_BUNDLE;
+ public static String ECLIPSE_MISSING_REQUIRED_BUNDLE;
+ public static String ECLIPSE_MISSING_HOST;
+ public static String ECLIPSE_CANNOT_CHANGE_LOCATION;
+ public static String ECLIPSE_BUNDLESTOPPER_CYCLES_FOUND;
+ public static String ECLIPSE_BUNDLESTOPPER_ERROR_STOPPING_BUNDLE;
+ public static String ECLIPSE_CACHEDMANIFEST_UNEXPECTED_EXCEPTION;
+
+ public static String fileManager_cannotLock;
+ public static String fileManager_couldNotSave;
+ public static String fileManager_updateFailed;
+ public static String fileManager_illegalInReadOnlyMode;
+ public static String fileManager_notOpen;
+
+ public static String ECLIPSE_ADAPTOR_ERROR_XML_SERVICE;
+ public static String ECLIPSE_ADAPTOR_RUNTIME_ERROR;
+ public static String ECLIPSE_ADAPTOR_EXITING;
+
+ public static String ECLIPSE_DATA_MANIFEST_NOT_FOUND;
+ public static String ECLIPSE_CONVERTER_ERROR_CONVERTING;
+ public static String ECLIPSE_DATA_ERROR_READING_MANIFEST;
+ public static String ECLIPSE_CLASSLOADER_CANNOT_GET_HEADERS;
+
+ public static String ECLIPSE_CLASSLOADER_CONCURRENT_STARTUP;
+ public static String ECLIPSE_CLASSLOADER_ACTIVATION;
+ public static String ECLIPSE_CLASSLOADER_ALREADY_STOPPED;
+ public static String ECLIPSE_CLASSLOADER_GENERATED_EXCEPTION;
+ public static String ECLIPSE_CLASSLOADER_CANNOT_SET_CONTEXTFINDER;
+
+ public static String ECLIPSE_CONSOLE_COMMANDS_HEADER;
+ public static String ECLIPSE_CONSOLE_HELP_DIAG_COMMAND_DESCRIPTION;
+ public static String ECLIPSE_CONSOLE_HELP_ACTIVE_COMMAND_DESCRIPTION;
+ public static String ECLIPSE_CONSOLE_HELP_GETPROP_COMMAND_DESCRIPTION;
+ public static String ECLIPSE_CONSOLE_NO_BUNDLE_SPECIFIED_ERROR;
+ public static String ECLIPSE_CONSOLE_NO_CONSTRAINTS_NO_PLATFORM_ADMIN_MESSAGE;
+ public static String ECLIPSE_CONSOLE_CANNOT_FIND_BUNDLE_ERROR;
+ public static String ECLIPSE_CONSOLE_NO_CONSTRAINTS;
+ public static String ECLIPSE_CONSOLE_OTHER_VERSION;
+ public static String ECLIPSE_CONSOLE_BUNDLES_ACTIVE;
+
+ public static String ECLIPSE_STARTUP_ALREADY_RUNNING;
+ public static String ECLIPSE_STARTUP_STARTUP_ERROR;
+ public static String ECLIPSE_STARTUP_SHUTDOWN_ERROR;
+ public static String ECLIPSE_STARTUP_ERROR_CHECK_LOG;
+ public static String ECLIPSE_STARTUP_NOT_RUNNING;
+ public static String ECLIPSE_STARTUP_ERROR_NO_APPLICATION;
+ public static String ECLIPSE_STARTUP_ROOTS_NOT_RESOLVED;
+ public static String ECLIPSE_STARTUP_ALL_NOT_RESOLVED;
+ public static String ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_ACTIVE;
+ public static String ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_RESOLVED;
+ public static String ECLIPSE_STARTUP_BUNDLE_NOT_FOUND;
+ public static String ECLIPSE_STARTUP_INVALID_PORT;
+ public static String ECLIPSE_STARTUP_FAILED_FIND;
+ public static String ECLIPSE_STARTUP_FAILED_UNINSTALL;
+ public static String ECLIPSE_STARTUP_FAILED_INSTALL;
+ public static String ECLIPSE_STARTUP_FAILED_START;
+ public static String ECLIPSE_STARTUP_APP_ERROR;
+ public static String ECLIPSE_STARTUP_FILEMANAGER_OPEN_ERROR;
+ public static String ECLIPSE_STARTUP_PROPS_NOT_SET;
+
+ public static String error_badNL;
+
+ public static String location_cannotLock;
+ public static String location_cannotLockNIO;
+
+ public static String ECLIPSE_CONVERTER_FILENOTFOUND;
+ public static String ECLIPSE_CONVERTER_ERROR_CREATING_BUNDLE_MANIFEST;
+ public static String ECLIPSE_CONVERTER_PLUGIN_LIBRARY_IGNORED;
+
+ public static String ECLIPSE_CONVERTER_ERROR_PARSING_PLUGIN_MANIFEST;
+ public static String ECLIPSE_CONVERTER_MISSING_ATTRIBUTE;
+ public static String parse_error;
+ public static String parse_errorNameLineColumn;
+
+ public static String ECLIPSE_CONVERTER_NO_SAX_FACTORY;
+ public static String ECLIPSE_CONVERTER_PARSE_UNKNOWNTOP_ELEMENT;
+
+ public static final String NEW_LINE = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ static {
+ // initialize resource bundles
+ NLS.initializeMessages(BUNDLE_NAME, EclipseAdaptorMsg.class);
+ }
+
+ public static String getResolutionFailureMessage(VersionConstraint unsatisfied) {
+ if (unsatisfied.isResolved())
+ throw new IllegalArgumentException();
+ if (unsatisfied instanceof ImportPackageSpecification)
+ return NLS.bind(ECLIPSE_MISSING_IMPORTED_PACKAGE, toString(unsatisfied));
+ else if (unsatisfied instanceof BundleSpecification)
+ if (((BundleSpecification) unsatisfied).isOptional())
+ return NLS.bind(ECLIPSE_MISSING_OPTIONAL_REQUIRED_BUNDLE, toString(unsatisfied));
+ else
+ return NLS.bind(ECLIPSE_MISSING_REQUIRED_BUNDLE, toString(unsatisfied));
+ else
+ return NLS.bind(ECLIPSE_MISSING_HOST, toString(unsatisfied));
+ }
+
+ /**
+ * Print a debug message to the console.
+ * Pre-pend the message with the current date and the name of the current thread.
+ */
+ public static void debug(String message) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(new Date(System.currentTimeMillis()));
+ buffer.append(" - ["); //$NON-NLS-1$
+ buffer.append(Thread.currentThread().getName());
+ buffer.append("] "); //$NON-NLS-1$
+ buffer.append(message);
+ System.out.println(buffer.toString());
+ }
+
+ private static String toString(VersionConstraint constraint) {
+ org.eclipse.osgi.service.resolver.VersionRange versionRange = constraint.getVersionRange();
+ if (versionRange == null)
+ return constraint.getName();
+ return constraint.getName() + '_' + versionRange;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/Locker_JavaNio.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/Locker_JavaNio.java
index ee8ce4914..6b7ed956b 100644
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/Locker_JavaNio.java
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/core/runtime/internal/adaptor/Locker_JavaNio.java
@@ -12,7 +12,6 @@ package org.eclipse.core.runtime.internal.adaptor;
import java.io.*;
import java.nio.channels.FileLock;
-import org.eclipse.core.runtime.adaptor.EclipseAdaptorMsg;
import org.eclipse.osgi.util.NLS;
/**
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFile.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFile.java
index a03cc3e83..0321479b0 100644
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFile.java
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFile.java
@@ -501,6 +501,7 @@ public class ReliableFile {
* Answers a boolean indicating whether or not the specified reliable file
* exists on the underlying file system. This call only returns if a file
* exists and not if the file contents are valid.
+ * @param file returns true if the specified reliable file exists; otherwise false is returned
*
* @return <code>true</code> if the specified reliable file exists,
* <code>false</code> otherwise.
@@ -573,6 +574,7 @@ public class ReliableFile {
/**
* Delete the specified reliable file on the underlying file system.
+ * @param deleteFile the reliable file to delete
*
* @return <code>true</code> if the specified reliable file was deleted,
* <code>false</code> otherwise.
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileInputStream.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileInputStream.java
index c817fda06..e1dffe8a4 100644
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileInputStream.java
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileInputStream.java
@@ -120,6 +120,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default FilterInputStream method.
+ * @see FilterInputStream#read(byte[], int, int)
*/
public synchronized int read(byte b[], int off, int len) throws IOException {
if (readPos >= length) {
@@ -138,6 +139,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default FilterInputStream method.
+ * @see FilterInputStream#read(byte[])
*/
public synchronized int read(byte b[]) throws IOException {
return read(b, 0, b.length);
@@ -145,6 +147,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default FilterInputStream method.
+ * @see FilterInputStream#read()
*/
public synchronized int read() throws IOException {
if (readPos >= length) {
@@ -160,6 +163,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default available method.
+ * @see FilterInputStream#available()
*/
public synchronized int available() throws IOException {
if (readPos < length) // just in case
@@ -169,6 +173,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default skip method.
+ * @see FilterInputStream#skip(long)
*/
public synchronized long skip(long n) throws IOException {
long len = super.skip(n);
@@ -180,6 +185,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default markSupported method.
+ * @see FilterInputStream#markSupported()
*/
public boolean markSupported() {
return false;
@@ -187,6 +193,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default mark method.
+ * @see FilterInputStream#mark(int)
*/
public void mark(int readlimit) {
//ignore
@@ -194,6 +201,7 @@ public class ReliableFileInputStream extends FilterInputStream {
/**
* Override default reset method.
+ * @see FilterInputStream#reset()
*/
public void reset() throws IOException {
throw new IOException("reset not supported."); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileOutputStream.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileOutputStream.java
index a67f88f54..3c2a3a099 100644
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileOutputStream.java
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/internal/reliablefile/ReliableFileOutputStream.java
@@ -142,6 +142,7 @@ public class ReliableFileOutputStream extends FilterOutputStream {
/**
* Override default FilterOutputStream method.
+ * @see FilterOutputStream#write(byte[])
*/
public void write(byte[] b) throws IOException {
this.write(b, 0, b.length);
@@ -149,6 +150,7 @@ public class ReliableFileOutputStream extends FilterOutputStream {
/**
* Override default FilterOutputStream method.
+ * @see FilterOutputStream#write(byte[], int, int)
*/
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
@@ -157,6 +159,7 @@ public class ReliableFileOutputStream extends FilterOutputStream {
/**
* Override default FilterOutputStream method.
+ * @see FilterOutputStream#write(int)
*/
public void write(int b) throws IOException {
out.write(b);
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/service/datalocation/Location.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/service/datalocation/Location.java
index b8fba576e..6b1ebe3a9 100644
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/service/datalocation/Location.java
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/service/datalocation/Location.java
@@ -128,6 +128,7 @@ public interface Location {
* Locking a location is advisory only. That is, it does not prevent other applications from
* modifying the same location
* </p>
+ * @return true if the lock could be acquired; otherwise false is returned
*
* @exception IOException if there was an unexpected problem while acquiring the lock
*/
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/service/localization/BundleLocalization.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/service/localization/BundleLocalization.java
index 7e4fa4586..2061517ba 100644
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/service/localization/BundleLocalization.java
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/service/localization/BundleLocalization.java
@@ -26,6 +26,8 @@ public interface BundleLocalization {
/**
* The getLocalization method gets a ResourceBundle object for the given
* locale and bundle.
+ * @param bundle the bundle to get localization for
+ * @param locale the name of the locale to get
*
* @return A <code>ResourceBundle</code> object for the given bundle and locale.
* If <code>null</code> is passed for the locale parameter, the default locale is used.
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/storagemanager/ManagedOutputStream.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/storagemanager/ManagedOutputStream.java
index 7a3aaaf0c..4c4cf045d 100644
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/storagemanager/ManagedOutputStream.java
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/storagemanager/ManagedOutputStream.java
@@ -46,6 +46,7 @@ public final class ManagedOutputStream extends FilterOutputStream {
* a set returned by {@link StorageManager#getOutputStreamSet(String[])} then
* the storage manager will only be updated with the new content after all
* of the managed output streams in the set are closed successfully.
+ * @see FilterOutputStream#close()
*/
public void close() throws IOException {
manager.closeOutputStream(this);
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/storagemanager/StorageManager.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/storagemanager/StorageManager.java
index 1ab2e7901..09f973563 100644
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/storagemanager/StorageManager.java
+++ b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/storagemanager/StorageManager.java
@@ -12,9 +12,7 @@ package org.eclipse.osgi.storagemanager;
import java.io.*;
import java.util.*;
-import org.eclipse.core.runtime.adaptor.EclipseAdaptorMsg;
-import org.eclipse.core.runtime.internal.adaptor.BasicLocation;
-import org.eclipse.core.runtime.internal.adaptor.Locker;
+import org.eclipse.core.runtime.internal.adaptor.*;
import org.eclipse.osgi.framework.internal.reliablefile.*;
import org.eclipse.osgi.framework.util.SecureAction;
@@ -459,6 +457,7 @@ public final class StorageManager {
* Removes the given managed file from management by this storage manager.
*
* @param managedFile the managed file to remove
+ * @throws IOException if an error occured removing the managed file
*/
public void remove(String managedFile) throws IOException {
if (!open)
@@ -686,6 +685,7 @@ public final class StorageManager {
* This methods opens the storage manager.
* This method must be called before any operation on the storage manager.
* @param wait indicates if the open operation must wait in case of contention on the lock file.
+ * @throws IOException if an error occured opening the storage manager
*/
public void open(boolean wait) throws IOException {
if (openCleanup)

Back to the top