| author | Thomas Watson | 2011-03-15 16:56:47 (EDT) |
|---|---|---|
| committer | Glyn Normington | 2011-03-15 16:56:47 (EDT) |
| commit | ff5330d917696874d2d6bf7b269b49cbdb59c63e (patch) (side-by-side diff) | |
| tree | 9eb994349dc3f767031c045c22600ca0d46d2b0d | |
| parent | ab0f2c9183d64a4f7fe2593f4715b501e273dda9 (diff) | |
| download | org.eclipse.virgo.kernel-ff5330d917696874d2d6bf7b269b49cbdb59c63e.zip org.eclipse.virgo.kernel-ff5330d917696874d2d6bf7b269b49cbdb59c63e.tar.gz org.eclipse.virgo.kernel-ff5330d917696874d2d6bf7b269b49cbdb59c63e.tar.bz2 | |
Handle disconnected digraphs.
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(); |

