summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2011-03-15 16:56:47 (EDT)
committer Glyn Normington2011-03-15 16:56:47 (EDT)
commitff5330d917696874d2d6bf7b269b49cbdb59c63e (patch)
tree9eb994349dc3f767031c045c22600ca0d46d2b0d
parentab0f2c9183d64a4f7fe2593f4715b501e273dda9 (diff)
downloadorg.eclipse.virgo.kernel-ff5330d917696874d2d6bf7b269b49cbdb59c63e.zip
org.eclipse.virgo.kernel-ff5330d917696874d2d6bf7b269b49cbdb59c63e.tar.gz
org.eclipse.virgo.kernel-ff5330d917696874d2d6bf7b269b49cbdb59c63e.tar.bz2
Handle disconnected digraphs.
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/BundleIdBasedRegion.java15
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraph.java12
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraphPersistence.java17
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraphPeristenceTests.java55
4 files changed, 73 insertions, 26 deletions
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/BundleIdBasedRegion.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/BundleIdBasedRegion.java
index 8ebb78f..a5346a0 100644
--- a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/BundleIdBasedRegion.java
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/BundleIdBasedRegion.java
@@ -112,6 +112,8 @@ final class BundleIdBasedRegion implements Region {
*/
@Override
public Bundle installBundle(String location, InputStream input) throws BundleException {
+ if (this.systemBundleContext == null)
+ throw new BundleException("This region is not connected to an OSGi Framework.", BundleException.INVALID_OPERATION);
setRegionThreadLocal();
try {
return this.systemBundleContext.installBundle(this.regionName + REGION_LOCATION_DELIMITER + location, input);
@@ -125,6 +127,8 @@ final class BundleIdBasedRegion implements Region {
*/
@Override
public Bundle installBundle(String location) throws BundleException {
+ if (this.systemBundleContext == null)
+ throw new BundleException("This region is not connected to an OSGi Framework.", BundleException.INVALID_OPERATION);
setRegionThreadLocal();
try {
return this.systemBundleContext.installBundle(this.regionName + REGION_LOCATION_DELIMITER + location, openBundleStream(location));
@@ -134,11 +138,13 @@ final class BundleIdBasedRegion implements Region {
}
private void setRegionThreadLocal() {
- this.threadLocal.set(this);
+ if (this.threadLocal != null)
+ this.threadLocal.set(this);
}
private void removeRegionThreadLocal() {
- this.threadLocal.remove();
+ if (this.threadLocal != null)
+ this.threadLocal.remove();
}
private InputStream openBundleStream(String location) throws BundleException {
@@ -170,7 +176,8 @@ final class BundleIdBasedRegion implements Region {
*/
@Override
public Bundle getBundle(@NonNull String symbolicName, @NonNull Version version) {
-
+ if (this.systemBundleContext == null)
+ return null; // this region is not connected to an OSGi framework
// The following iteration is weakly consistent and will never throw ConcurrentModificationException.
for (long bundleId : this.bundleIds) {
Bundle bundle = this.systemBundleContext.getBundle(bundleId);
@@ -276,7 +283,7 @@ final class BundleIdBasedRegion implements Region {
@Override
public void visitSubgraph(RegionDigraphVisitor visitor) {
- this.regionDigraph.visitSubgraph(this, visitor);
+ this.regionDigraph.visitSubgraph(this, visitor);
}
}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraph.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraph.java
index 2906f8f..ce15f2e 100644
--- a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraph.java
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraph.java
@@ -56,11 +56,15 @@ public final class StandardRegionDigraph implements RegionDigraph {
private final ThreadLocal<Region> threadLocal;
- private SubgraphTraverser subgraphTraverser;
+ private final SubgraphTraverser subgraphTraverser;
+
+ StandardRegionDigraph() {
+ this(null, null);
+ }
public StandardRegionDigraph(BundleContext bundleContext, ThreadLocal<Region> threadLocal) {
this.subgraphTraverser = new SubgraphTraverser();
- this.systemBundleContext = bundleContext.getBundle(0L).getBundleContext();
+ this.systemBundleContext = bundleContext == null ? null : bundleContext.getBundle(0L).getBundleContext();
this.threadLocal = threadLocal;
}
@@ -290,6 +294,8 @@ public final class StandardRegionDigraph implements RegionDigraph {
private Set<RegionLifecycleListener> getListeners() {
Set<RegionLifecycleListener> listeners = new HashSet<RegionLifecycleListener>();
+ if (this.systemBundleContext == null)
+ return listeners;
try {
Collection<ServiceReference<RegionLifecycleListener>> listenerServiceReferences = this.systemBundleContext.getServiceReferences(
RegionLifecycleListener.class, null);
@@ -330,6 +336,6 @@ public final class StandardRegionDigraph implements RegionDigraph {
@Override
public RegionDigraphPersistence getRegionDigraphPersistence() {
- return new StandardRegionDigraphPersistence(systemBundleContext, threadLocal);
+ return new StandardRegionDigraphPersistence();
}
}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraphPersistence.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraphPersistence.java
index cfbe4c6..810cb0a 100644
--- a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraphPersistence.java
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraphPersistence.java
@@ -26,7 +26,6 @@ import org.eclipse.virgo.kernel.osgi.region.RegionDigraph.FilteredRegion;
import org.eclipse.virgo.kernel.osgi.region.RegionDigraphPersistence;
import org.eclipse.virgo.kernel.osgi.region.RegionFilter;
import org.eclipse.virgo.kernel.osgi.region.RegionFilterBuilder;
-import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.InvalidSyntaxException;
@@ -105,9 +104,8 @@ final class StandardRegionDigraphPersistence implements RegionDigraphPersistence
}
}
- static RegionDigraph readRegionDigraph(DataInputStream in, BundleContext systemBundleContext, ThreadLocal<Region> threadLocal)
- throws IOException, InvalidSyntaxException, BundleException {
- RegionDigraph digraph = new StandardRegionDigraph(systemBundleContext, threadLocal);
+ static RegionDigraph readRegionDigraph(DataInputStream in) throws IOException, InvalidSyntaxException, BundleException {
+ RegionDigraph digraph = new StandardRegionDigraph();
// read the number of regions
int numRegions = in.readInt();
@@ -170,19 +168,10 @@ final class StandardRegionDigraphPersistence implements RegionDigraphPersistence
digraph.connect(tail, builder.build(), head);
}
- private final BundleContext context;
-
- private final ThreadLocal<Region> threadLocal;
-
- public StandardRegionDigraphPersistence(BundleContext context, ThreadLocal<Region> threadLocal) {
- this.context = context;
- this.threadLocal = threadLocal;
- }
-
@Override
public RegionDigraph load(InputStream input) throws IOException {
try {
- return readRegionDigraph(new DataInputStream(input), context, threadLocal);
+ return readRegionDigraph(new DataInputStream(input));
} catch (InvalidSyntaxException e) {
// This should never happen since the filters were valid on save
// propagate as IllegalStateException
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraphPeristenceTests.java b/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraphPeristenceTests.java
index 7d9d23f..8e45160 100644
--- a/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraphPeristenceTests.java
+++ b/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/internal/StandardRegionDigraphPeristenceTests.java
@@ -37,6 +37,7 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
@@ -56,9 +57,8 @@ public class StandardRegionDigraphPeristenceTests {
@Before
public void setUp() throws Exception {
- long nextId = 0;
- StubBundle stubSystemBundle = new StubBundle(nextId++, "osgi.framework", new Version("0"), "loc");
- systemBundleContext = new StubBundleContext();
+ StubBundle stubSystemBundle = new StubBundle(0L, "osgi.framework", new Version("0"), "loc");
+ systemBundleContext = (StubBundleContext) stubSystemBundle.getBundleContext();
systemBundleContext.addInstalledBundle(stubSystemBundle);
threadLocal = new ThreadLocal<Region>();
this.digraph = new StandardRegionDigraph(systemBundleContext, threadLocal);
@@ -69,7 +69,9 @@ public class StandardRegionDigraphPeristenceTests {
Region region = digraph.createRegion(regionName);
for (int i = 0; i < 10; i++) {
String bsn = region.getName() + "." + i;
- region.addBundle(new StubBundle(nextId++, bsn, new Version("0"), bsn));
+ StubBundle b = (StubBundle) systemBundleContext.installBundle(bsn);
+ systemBundleContext.addInstalledBundle(b);
+ region.addBundle(b);
}
}
}
@@ -130,6 +132,37 @@ public class StandardRegionDigraphPeristenceTests {
doTest();
}
+ @Test
+ public void testInvalidOperations() throws IOException, InvalidSyntaxException, BundleException {
+ Region boot = digraph.getRegion(BOOT_REGION);
+ Bundle b = boot.installBundle("dynamic.add.a.1", null);
+ // needed because we don't have a bundle hook to add it for us
+ boot.addBundle(b);
+ // needed because StubBundleContext.installBundle does not do this!
+ systemBundleContext.addInstalledBundle((StubBundle) b);
+ Bundle p = boot.getBundle(b.getSymbolicName(), b.getVersion());
+ Assert.assertEquals(b, p);
+ // TODO seems testing this will require a reference handler to be present
+ // b = boot.installBundle("file:dynamic.add.a.2");
+ // boot.addBundle(b); // needed because we don't have a bundle hook to add it for us
+
+ RegionDigraph copy = copy(digraph);
+ Region bootCopy = copy.getRegion(BOOT_REGION);
+ p = bootCopy.getBundle(b.getSymbolicName(), b.getVersion());
+ Assert.assertNull(p);
+ try {
+ bootCopy.installBundle("dynamic.add.b.1", null);
+ } catch (BundleException e) {
+ // expected
+ }
+ try {
+ bootCopy.installBundle("dynamic.add.b.2");
+ } catch (BundleException e) {
+ // expected
+ }
+
+ }
+
private void doTest() throws IOException, InvalidSyntaxException, BundleException {
// test a single write
doTest(1);
@@ -137,6 +170,18 @@ public class StandardRegionDigraphPeristenceTests {
doTest(10);
}
+ private RegionDigraph copy(RegionDigraph toCopy) throws IOException, InvalidSyntaxException, BundleException {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ DataOutputStream dataOut = new DataOutputStream(output);
+ StandardRegionDigraphPersistence.writeRegionDigraph(new DataOutputStream(output), digraph);
+ dataOut.close();
+
+ DataInputStream dataIn = new DataInputStream(new ByteArrayInputStream(output.toByteArray()));
+ RegionDigraph copy = StandardRegionDigraphPersistence.readRegionDigraph(dataIn);
+ dataIn.close();
+ return copy;
+ }
+
private void doTest(int iterations) throws IOException, InvalidSyntaxException, BundleException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
DataOutputStream dataOut = new DataOutputStream(output);
@@ -147,7 +192,7 @@ public class StandardRegionDigraphPeristenceTests {
DataInputStream dataIn = new DataInputStream(new ByteArrayInputStream(output.toByteArray()));
for (int i = 0; i < iterations; i++) {
- RegionDigraph copy = StandardRegionDigraphPersistence.readRegionDigraph(dataIn, systemBundleContext, threadLocal);
+ RegionDigraph copy = StandardRegionDigraphPersistence.readRegionDigraph(dataIn);
assertEquals(digraph, copy);
}
dataIn.close();