fixes for composite update clarifications.
diff --git a/bundles/org.eclipse.osgi/core/composite/org/eclipse/osgi/internal/composite/CompositeImpl.java b/bundles/org.eclipse.osgi/core/composite/org/eclipse/osgi/internal/composite/CompositeImpl.java
index 6c2b9ea..908c0f2 100644
--- a/bundles/org.eclipse.osgi/core/composite/org/eclipse/osgi/internal/composite/CompositeImpl.java
+++ b/bundles/org.eclipse.osgi/core/composite/org/eclipse/osgi/internal/composite/CompositeImpl.java
@@ -39,6 +39,12 @@
public class CompositeImpl extends BundleHost implements CompositeBundle {
private static final StateObjectFactory stateFactory = new StateObjectFactoryImpl();
+ private static final ThreadLocal<Boolean> updating = new ThreadLocal<Boolean>() {
+ public Boolean initialValue() {
+ return Boolean.FALSE;
+ }
+ };
+
private final CompositeSystemBundle compositeSystemBundle;
private final CompositeInfo compositeInfo;
private final StartLevelManager startLevelManager;
@@ -145,6 +151,10 @@
}
public void update(InputStream in) throws BundleException {
+ if (in == RELOAD) {
+ super.update(RELOAD);
+ return;
+ }
try {
in.close();
} catch (IOException e) {
@@ -172,10 +182,13 @@
config.load(configURL.openStream());
// get an in memory input stream to jar content of the composite we want to install
InputStream content = CompositeSupport.getCompositeInput(config, compositeManifest);
+ updating.set(true);
// update with the new content
super.update(content);
} catch (IOException e) {
throw new BundleException("Error creating composite bundle", e); //$NON-NLS-1$
+ } finally {
+ updating.set(false);
}
}
@@ -185,6 +198,16 @@
// update the composite info with the new data.
CompositeInfo updatedInfo = createCompositeInfo(getBundleId(), false);
compositeInfo.update(updatedInfo);
+ AbstractBundle[] bundles = framework.getBundles(getBundleId());
+ // reload all the constituents
+ for (AbstractBundle bundle : bundles) {
+ if (bundle.getBundleId() != 0) // not the system bundle
+ try {
+ bundle.reload();
+ } catch (BundleException e) {
+ framework.publishFrameworkEvent(FrameworkEvent.ERROR, bundle, e);
+ }
+ }
}
protected void startHook() {
@@ -192,7 +215,10 @@
}
protected void stopHook() {
- startLevelManager.shutdown();
+ if (updating.get())
+ startLevelManager.update();
+ else
+ startLevelManager.shutdown();
}
public void uninstallWorkerPrivileged() throws BundleException {
@@ -342,10 +368,6 @@
return (String) configuration.setProperty(key, value);
}
- protected void load() {
- super.load();
- }
-
protected void refresh() {
super.refresh();
loadConstituents();
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 63ec6c8..3330406 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
@@ -10,8 +10,7 @@
*******************************************************************************/
package org.eclipse.osgi.framework.internal.core;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.*;
@@ -36,6 +35,7 @@
* This class is abstract and is extended by BundleHost and BundleFragment.
*/
public abstract class AbstractBundle implements Bundle, Comparable<Bundle>, KeyedElement, BundleStartLevel {
+ protected static final InputStream RELOAD = new ByteArrayInputStream(new byte[0]);
/** The Framework this bundle is part of */
protected final Framework framework;
/** The state of the bundle. */
@@ -557,6 +557,10 @@
update(null);
}
+ public void reload() throws BundleException {
+ update(RELOAD);
+ }
+
public void update(final InputStream in) throws BundleException {
if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
Debug.println("update location " + bundledata.getLocation()); //$NON-NLS-1$
@@ -583,6 +587,8 @@
Debug.println(" from location: " + updateLocation); //$NON-NLS-1$
/* Map the update location to a URLConnection */
source = framework.adaptor.mapLocationToURLConnection(updateLocation);
+ } else if (in == RELOAD) {
+ source = null;
} else {
/* Map the InputStream to a URLConnection */
source = new BundleSource(in);
@@ -591,7 +597,7 @@
updateWorkerPrivileged(source, callerContext);
return null;
}
- });
+ }, in == RELOAD);
} finally {
completeStateChange();
}
@@ -600,7 +606,7 @@
/**
* Update worker. Assumes the caller has the state change lock.
*/
- protected void updateWorker(PrivilegedExceptionAction action) throws BundleException {
+ final void updateWorker(PrivilegedExceptionAction action, boolean reload) throws BundleException {
int previousState = 0;
if (!isFragment())
previousState = state;
@@ -616,7 +622,8 @@
}
try {
AccessController.doPrivileged(action);
- framework.publishBundleEvent(BundleEvent.UPDATED, this);
+ if (!reload)
+ framework.publishBundleEvent(BundleEvent.UPDATED, this);
} catch (PrivilegedActionException pae) {
if (pae.getException() instanceof RuntimeException)
throw (RuntimeException) pae.getException();
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java
index b7fdb58..098452f 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java
@@ -214,13 +214,11 @@
doSetStartLevel(0);
}
- /**
- * Internal worker method to set the startlevel
- *
- * @param newSL start level value
- * @param callerBundle - the bundle initiating the change in start level
- */
- public void doSetStartLevel(int newSL) {
+ public void update() {
+ doSetStartLevel(0, FrameworkEvent.STOPPED_UPDATE);
+ }
+
+ private void doSetStartLevel(int newSL, int frameworkEvent) {
synchronized (lock) {
ClassLoader previousTCCL = Thread.currentThread().getContextClassLoader();
ClassLoader contextFinder = framework.getContextFinder();
@@ -261,7 +259,7 @@
}
if (newSL == 0) {
// stop and unload all bundles
- stopSystemBundle();
+ stopSystemBundle(frameworkEvent);
unloadAllBundles(framework.bundles);
}
}
@@ -276,6 +274,16 @@
}
}
+ /**
+ * Internal worker method to set the startlevel
+ *
+ * @param newSL start level value
+ * @param callerBundle - the bundle initiating the change in start level
+ */
+ public void doSetStartLevel(int newSL) {
+ doSetStartLevel(newSL, FrameworkEvent.STOPPED);
+ }
+
/**
* This method is used within the package to save the actual active startlevel value for the framework.
* Externally the setStartLevel method must be used.
@@ -602,7 +610,7 @@
/**
* Stop the system bundle
*/
- private void stopSystemBundle() {
+ private void stopSystemBundle(int frameworkEvent) {
try {
systemBundle.context.stop();
} catch (BundleException sbe) {
@@ -617,7 +625,7 @@
framework.publishBundleEvent(BundleEvent.STOPPED, systemBundle);
if (systemBundle.getCompositeId() > 0) {
// TODO warning this is hacky should encapsulate this in CompositeImpl somehow
- framework.publishFrameworkEvent(FrameworkEvent.STOPPED, systemBundle, null);
+ framework.publishFrameworkEvent(frameworkEvent, systemBundle, null);
systemBundle.state = Bundle.STARTING;
framework.publishBundleEvent(BundleEvent.STARTING, systemBundle);
}
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
index 918c24d..9aae872 100644
--- 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2010 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
@@ -24,10 +24,10 @@
import org.osgi.framework.*;
public class BundleUpdate implements BundleOperation {
- private BaseData data;
+ private final BaseData data;
+ private final URLConnection source;
+ private final BaseStorage storage;
private BaseData newData;
- private URLConnection source;
- private BaseStorage storage;
public BundleUpdate(BaseData data, URLConnection source, BaseStorage storage) {
this.data = data;
@@ -42,6 +42,10 @@
* @throws BundleException if an error occurs
*/
public BundleData begin() throws BundleException {
+ if (source == null) {
+ newData = data;
+ return newData;
+ }
try {
newData = storage.createBaseData(data.getBundleID(), data.getCompositeID(), data.getLocation());
newData.setLastModified(System.currentTimeMillis());
@@ -115,6 +119,10 @@
*/
public void commit(boolean postpone) throws BundleException {
+ if (newData == data) {
+ storage.updateState(newData, BundleEvent.UPDATED);
+ return;
+ }
storage.processExtension(data, BaseStorage.EXTENSION_UNINSTALLED); // remove the old extension
storage.processExtension(newData, BaseStorage.EXTENSION_UPDATED); // update to the new one
try {
@@ -138,6 +146,8 @@
* @throws BundleException If a failure occured modifiying peristent storage.
*/
public void undo() throws BundleException {
+ if (newData == data)
+ return;
if (newData != null) {
BaseStorageHook newStorageHook = (BaseStorageHook) newData.getStorageHook(BaseStorageHook.KEY);
try {