Modified: aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/DynamicImportTest.java URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/DynamicImportTest.java?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/DynamicImportTest.java (original) +++ aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/DynamicImportTest.java Wed Jan 7 19:37:42 2015 @@ -6,6 +6,7 @@ import static org.junit.Assert.assertTru import static org.junit.Assert.fail; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -79,7 +80,8 @@ public class DynamicImportTest extends S } } - @Test + @SuppressWarnings("rawtypes") + @Test public void testFirstPassWeavingApproach() throws Exception { ServiceRegistration<?> sr = bundleContext.registerService(WeavingHook.class, new TokenWeaver(), null); @@ -133,7 +135,8 @@ public class DynamicImportTest extends S * added to the region's sharing policy even if the subsystem has no * Import-Package header. */ - @Test + @SuppressWarnings("rawtypes") + @Test public void testDynamicPackageImportsAddedToSharingPolicyWhenNoImportPackageHeader() throws Exception { final AtomicBoolean weavingHookCalled = new AtomicBoolean(false); ServiceRegistration reg = bundleContext.registerService( @@ -178,4 +181,80 @@ public class DynamicImportTest extends S catch (Exception e) {} } } + + protected static final byte[] EMPTY_CLASS = new byte[] { + (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x32, + (byte)0x00, (byte)0x12, (byte)0x07, (byte)0x00, + (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x05, + (byte)0x45, (byte)0x6d, (byte)0x70, (byte)0x74, + (byte)0x79, (byte)0x07, (byte)0x00, (byte)0x04, + (byte)0x01, (byte)0x00, (byte)0x10, (byte)0x6a, + (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, + (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, + (byte)0x2f, (byte)0x4f, (byte)0x62, (byte)0x6a, + (byte)0x65, (byte)0x63, (byte)0x74, (byte)0x07, + (byte)0x00, (byte)0x06, (byte)0x01, (byte)0x00, + (byte)0x14, (byte)0x6a, (byte)0x61, (byte)0x76, + (byte)0x61, (byte)0x2f, (byte)0x69, (byte)0x6f, + (byte)0x2f, (byte)0x53, (byte)0x65, (byte)0x72, + (byte)0x69, (byte)0x61, (byte)0x6c, (byte)0x69, + (byte)0x7a, (byte)0x61, (byte)0x62, (byte)0x6c, + (byte)0x65, (byte)0x01, (byte)0x00, (byte)0x06, + (byte)0x3c, (byte)0x69, (byte)0x6e, (byte)0x69, + (byte)0x74, (byte)0x3e, (byte)0x01, (byte)0x00, + (byte)0x03, (byte)0x28, (byte)0x29, (byte)0x56, + (byte)0x01, (byte)0x00, (byte)0x04, (byte)0x43, + (byte)0x6f, (byte)0x64, (byte)0x65, (byte)0x0a, + (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x0b, + (byte)0x0c, (byte)0x00, (byte)0x07, (byte)0x00, + (byte)0x08, (byte)0x01, (byte)0x00, (byte)0x0f, + (byte)0x4c, (byte)0x69, (byte)0x6e, (byte)0x65, + (byte)0x4e, (byte)0x75, (byte)0x6d, (byte)0x62, + (byte)0x65, (byte)0x72, (byte)0x54, (byte)0x61, + (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0x01, + (byte)0x00, (byte)0x12, (byte)0x4c, (byte)0x6f, + (byte)0x63, (byte)0x61, (byte)0x6c, (byte)0x56, + (byte)0x61, (byte)0x72, (byte)0x69, (byte)0x61, + (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0x54, + (byte)0x61, (byte)0x62, (byte)0x6c, (byte)0x65, + (byte)0x01, (byte)0x00, (byte)0x04, (byte)0x74, + (byte)0x68, (byte)0x69, (byte)0x73, (byte)0x01, + (byte)0x00, (byte)0x07, (byte)0x4c, (byte)0x45, + (byte)0x6d, (byte)0x70, (byte)0x74, (byte)0x79, + (byte)0x3b, (byte)0x01, (byte)0x00, (byte)0x0a, + (byte)0x53, (byte)0x6f, (byte)0x75, (byte)0x72, + (byte)0x63, (byte)0x65, (byte)0x46, (byte)0x69, + (byte)0x6c, (byte)0x65, (byte)0x01, (byte)0x00, + (byte)0x0a, (byte)0x45, (byte)0x6d, (byte)0x70, + (byte)0x74, (byte)0x79, (byte)0x2e, (byte)0x6a, + (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x00, + (byte)0x21, (byte)0x00, (byte)0x01, (byte)0x00, + (byte)0x03, (byte)0x00, (byte)0x01, (byte)0x00, + (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x00, + (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, + (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x2f, (byte)0x00, + (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x2a, + (byte)0xb7, (byte)0x00, (byte)0x0a, (byte)0xb1, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, + (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x01, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04, + (byte)0x00, (byte)0x0d, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x01, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, + (byte)0x00, (byte)0x0e, (byte)0x00, (byte)0x0f, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, + (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x11 + }; + + protected static void createEmptyClass() throws IOException { + FileOutputStream fos = new FileOutputStream("Empty.class"); + fos.write(EMPTY_CLASS); + fos.close(); + } }
Modified: aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java (original) +++ aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java Wed Jan 7 19:37:42 2015 @@ -50,8 +50,8 @@ import org.apache.aries.itest.RichBundle import org.apache.aries.subsystem.AriesSubsystem; import org.apache.aries.subsystem.core.archive.ProvisionPolicyDirective; import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader; +import org.apache.aries.subsystem.core.archive.TypeAttribute; import org.apache.aries.subsystem.core.internal.BundleResource; -import org.apache.aries.subsystem.core.internal.ResourceHelper; import org.apache.aries.subsystem.core.internal.SubsystemIdentifier; import org.apache.aries.subsystem.itests.util.TestRepository; import org.apache.aries.subsystem.itests.util.Utils; @@ -65,11 +65,14 @@ import org.eclipse.equinox.region.Region import org.junit.After; import org.junit.Before; import org.junit.runner.RunWith; +import org.ops4j.io.StreamUtils; import org.ops4j.pax.exam.Configuration; +import org.ops4j.pax.exam.CoreOptions; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; import org.ops4j.pax.exam.spi.reactors.PerClass; +import org.ops4j.pax.tinybundles.core.TinyBundles; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; @@ -78,7 +81,6 @@ import org.osgi.framework.FrameworkEvent import org.osgi.framework.FrameworkListener; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceEvent; -import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceRegistration; import org.osgi.framework.Version; import org.osgi.framework.namespace.IdentityNamespace; @@ -86,6 +88,7 @@ import org.osgi.framework.startlevel.Bun import org.osgi.framework.startlevel.FrameworkStartLevel; import org.osgi.framework.wiring.BundleRevision; import org.osgi.framework.wiring.FrameworkWiring; +import org.osgi.resource.Capability; import org.osgi.resource.Resource; import org.osgi.service.repository.Repository; import org.osgi.service.subsystem.Subsystem; @@ -95,113 +98,18 @@ import org.osgi.service.subsystem.Subsys @RunWith(PaxExam.class) @ExamReactorStrategy(PerClass.class) public abstract class SubsystemTest extends AbstractIntegrationTest { - protected static boolean createdApplications = false; + private static final String SUBSYSTEM_CORE_NAME = "org.apache.aries.subsystem.core"; + protected static boolean createdApplications = false; boolean installModeler = true; - + boolean installConfigAdmin = false; + public SubsystemTest() { } - + public SubsystemTest(boolean installModeller) { this.installModeler = installModeller; } - - protected static class SubsystemEventHandler implements ServiceListener { - private static class ServiceEventInfo { - private final ServiceEvent event; - private final long id; - private final State state; - private final String symbolicName; - private final String type; - private final Version version; - - public ServiceEventInfo(ServiceEvent event) { - id = (Long)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_ID_PROPERTY); - state = (State)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_STATE_PROPERTY); - symbolicName = (String)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME_PROPERTY); - type = (String)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_TYPE_PROPERTY); - version = (Version)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_VERSION_PROPERTY); - this.event = event; - } - - public int getEventType() { - return event.getType(); - } - - public long getId() { - return id; - } - - public State getState() { - return state; - } - - public String getSymbolicName() { - return symbolicName; - } - - public String getType() { - return type; - } - - public Version getVersion() { - return version; - } - } - - private final Map<Long, List<ServiceEventInfo>> subsystemIdToEvents = new HashMap<Long, List<ServiceEventInfo>>(); - - public void clear() { - synchronized (subsystemIdToEvents) { - subsystemIdToEvents.clear(); - } - } - - public ServiceEventInfo poll(long subsystemId) throws InterruptedException { - return poll(subsystemId, 0); - } - - public ServiceEventInfo poll(long subsystemId, long timeout) throws InterruptedException { - List<ServiceEventInfo> events; - synchronized (subsystemIdToEvents) { - events = subsystemIdToEvents.get(subsystemId); - if (events == null) { - events = new ArrayList<ServiceEventInfo>(); - subsystemIdToEvents.put(subsystemId, events); - } - } - synchronized (events) { - if (events.isEmpty()) { - events.wait(timeout); - if (events.isEmpty()) { - return null; - } - } - return events.remove(0); - } - } - - public void serviceChanged(ServiceEvent event) { - Long subsystemId = (Long)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_ID_PROPERTY); - synchronized (subsystemIdToEvents) { - List<ServiceEventInfo> events = subsystemIdToEvents.get(subsystemId); - if (events == null) { - events = new ArrayList<ServiceEventInfo>(); - subsystemIdToEvents.put(subsystemId, events); - } - synchronized (events) { - events.add(new ServiceEventInfo(event)); - events.notify(); - } - } - } - - public int size() { - synchronized (subsystemIdToEvents) { - return subsystemIdToEvents.size(); - } - } - } - + public Option baseOptions() { String localRepo = getLocalRepo(); return composite( @@ -212,11 +120,11 @@ public abstract class SubsystemTest exte when(localRepo != null).useOptions(vmOption("-Dorg.ops4j.pax.url.mvn.localRepository=" + localRepo)) ); } - + @Configuration public Option[] configuration() throws Exception { - // The itests need private packages from the core subsystems bundle. - InputStream fragment = SubsystemTest.class.getClassLoader().getResourceAsStream("core.fragment/core.fragment.jar"); + new File("target").mkdirs(); + init(); return new Option[] { baseOptions(), systemProperty("org.osgi.framework.bsnversion").value("multiple"), @@ -224,13 +132,12 @@ public abstract class SubsystemTest exte mavenBundle("org.apache.aries", "org.apache.aries.util").versionAsInProject(), mavenBundle("org.apache.aries.application", "org.apache.aries.application.utils").versionAsInProject(), mavenBundle("org.apache.aries.application", "org.apache.aries.application.api").versionAsInProject(), - when(installModeler).useOptions( - mavenBundle("org.apache.aries.application", "org.apache.aries.application.modeller").versionAsInProject(), - mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint").versionAsInProject(), - mavenBundle("org.apache.aries.proxy", "org.apache.aries.proxy").versionAsInProject()), + when(installModeler).useOptions(modelerBundles()), + when(installConfigAdmin).useOptions( + mavenBundle("org.apache.felix", "org.apache.felix.configadmin").versionAsInProject()), mavenBundle("org.apache.aries.subsystem", "org.apache.aries.subsystem.api").versionAsInProject(), - streamBundle(fragment).noStart(), - mavenBundle("org.apache.aries.subsystem", "org.apache.aries.subsystem.core").versionAsInProject(), + mavenBundle("org.apache.aries.subsystem", SUBSYSTEM_CORE_NAME).versionAsInProject(), + streamBundle(createCoreFragment()).noStart(), mavenBundle("org.apache.aries.subsystem", "org.apache.aries.subsystem.itest.interfaces").versionAsInProject(), mavenBundle("org.apache.aries.testsupport", "org.apache.aries.testsupport.unit").versionAsInProject(), //mavenBundle("org.apache.felix", "org.apache.felix.resolver").versionAsInProject(), @@ -244,85 +151,106 @@ public abstract class SubsystemTest exte // org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=7777"), }; } - + + protected void init() throws Exception { + + } + + private Option modelerBundles() { + return CoreOptions.composite( + mavenBundle("org.apache.aries.application", "org.apache.aries.application.modeller").versionAsInProject(), + mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint").versionAsInProject(), + mavenBundle("org.apache.aries.proxy", "org.apache.aries.proxy").versionAsInProject()); + } + + /** + * The itests need private packages from the core subsystems bundle. + * So this fragment exports them. + * @return stream containing the fragment + */ + private InputStream createCoreFragment() { + return TinyBundles.bundle() + .set("Bundle-SymbolicName", SUBSYSTEM_CORE_NAME + ".fragment") + .set("Export-Package", "org.apache.aries.subsystem.core.internal,org.apache.aries.subsystem.core.archive") + .set("Fragment-Host", SUBSYSTEM_CORE_NAME) + .build(); + } + protected final SubsystemEventHandler subsystemEvents = new SubsystemEventHandler(); - - protected Collection<ServiceRegistration> serviceRegistrations = new ArrayList<ServiceRegistration>(); - + + @SuppressWarnings("rawtypes") + protected Collection<ServiceRegistration> serviceRegistrations = new ArrayList<ServiceRegistration>(); + @Before public void setUp() throws Exception { if (!createdApplications) { createApplications(); createdApplications = true; } - try { - bundleContext.getBundle(0).getBundleContext().addServiceListener(subsystemEvents, '(' + Constants.OBJECTCLASS + '=' + Subsystem.class.getName() + ')'); - } - catch (InvalidSyntaxException e) { - fail("Invalid filter: " + e.getMessage()); - } - assertSubsystemNotNull(getRootSubsystem()); + bundleContext.getBundle(0).getBundleContext().addServiceListener(subsystemEvents, '(' + Constants.OBJECTCLASS + '=' + Subsystem.class.getName() + ')'); } - - protected abstract void createApplications() throws Exception; - @After - public void tearDown() throws Exception + protected void createApplications() throws Exception { + } + + @SuppressWarnings("rawtypes") + @After + public void tearDown() throws Exception { bundleContext.removeServiceListener(subsystemEvents); for (ServiceRegistration registration : serviceRegistrations) Utils.unregisterQuietly(registration); serviceRegistrations.clear(); } - + protected RichBundleContext context(Subsystem subsystem) { return new RichBundleContext(subsystem.getBundleContext()); } - + protected void assertEmptySubsystem(Subsystem subsystem) { assertSymbolicName("org.apache.aries.subsystem.itests.subsystem.empty", subsystem); assertVersion("0", subsystem); assertType(SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION, subsystem); } - + protected void assertBundleState(int state, String symbolicName, Subsystem subsystem) { Bundle bundle = context(subsystem).getBundleByName(symbolicName); assertNotNull("Bundle not found: " + symbolicName, bundle); assertBundleState(bundle, state); } - + protected void assertBundleState(Bundle bundle, int state) { assertTrue("Wrong state: " + bundle + " [expected " + state + " but was " + bundle.getState() + "]", (bundle.getState() & state) != 0); } - + protected Subsystem assertChild(Subsystem parent, String symbolicName) { return assertChild(parent, symbolicName, null, null); } - + protected Subsystem assertChild(Subsystem parent, String symbolicName, Version version) { return assertChild(parent, symbolicName, version, null); } - + protected Subsystem assertChild(Subsystem parent, String symbolicName, Version version, String type) { Subsystem result = getChild(parent, symbolicName, version, type); assertNotNull("Child does not exist: " + symbolicName, result); return result; } - + protected void assertChild(Subsystem parent, Subsystem child) { Collection<Subsystem> children = new ArrayList<Subsystem>(1); children.add(child); assertChildren(parent, children); } - + protected void assertChildren(int size, Subsystem subsystem) { assertEquals("Wrong number of children", size, subsystem.getChildren().size()); } - + protected void assertChildren(Subsystem parent, Collection<Subsystem> children) { assertTrue("Parent did not contain all children", parent.getChildren().containsAll(children)); } - + protected void assertClassLoadable(String clazz, Bundle bundle) { try { bundle.loadClass(clazz); @@ -332,47 +260,33 @@ public abstract class SubsystemTest exte fail("Class " + clazz + " from bundle " + bundle + " should be loadable"); } } - + protected void assertConstituent(Subsystem subsystem, String symbolicName) { assertConstituent(subsystem, symbolicName, Version.emptyVersion); } - + protected void assertConstituent(Subsystem subsystem, String symbolicName, Version version) { assertConstituent(subsystem, symbolicName, version, IdentityNamespace.TYPE_BUNDLE); } - + protected void assertContituent(Subsystem subsystem, String symbolicName, String type) { assertConstituent(subsystem, symbolicName, Version.emptyVersion, type); } - + protected Resource assertConstituent(Subsystem subsystem, String symbolicName, Version version, String type) { Resource constituent = getConstituent(subsystem, symbolicName, version, type); assertNotNull("Constituent not found: " + symbolicName + ';' + version + ';' + type, constituent); return constituent; } - + protected void assertConstituents(int size, Subsystem subsystem) { assertEquals("Wrong number of constituents", size, subsystem.getConstituents().size()); } - - protected void assertDirectory(Subsystem subsystem) { - Bundle bundle = getSubsystemCoreBundle(); - File file = bundle.getDataFile("subsystem" + subsystem.getSubsystemId()); - assertNotNull("Subsystem data file was null", file); - assertTrue("Subsystem data file does not exist", file.exists()); - } - - protected void assertNotDirectory(Subsystem subsystem) { - Bundle bundle = getSubsystemCoreBundle(); - File file = bundle.getDataFile("subsystem" + subsystem.getSubsystemId()); - assertNotNull("Subsystem data file was null", file); - assertFalse("Subsystem data file exists", file.exists()); - } - + protected void assertEvent(Subsystem subsystem, Subsystem.State state) throws InterruptedException { assertEvent(subsystem, state, 0); } - + protected void assertEvent(Subsystem subsystem, Subsystem.State state, long timeout) throws InterruptedException { assertEvent(subsystem, state, subsystemEvents.poll(subsystem.getSubsystemId(), timeout)); } @@ -382,7 +296,7 @@ public abstract class SubsystemTest exte else assertEvent(subsystem, state, event, ServiceEvent.MODIFIED); } - + protected void assertEvent(Subsystem subsystem, Subsystem.State state, SubsystemEventHandler.ServiceEventInfo event, int type) { // TODO Could accept a ServiceRegistration as an argument and verify it against the one in the event. assertNotNull("No event", event); @@ -393,64 +307,64 @@ public abstract class SubsystemTest exte assertEquals("Wrong state", state, event.getState()); assertEquals("Wrong event type", type, event.getEventType()); } - + protected String assertHeaderExists(Subsystem subsystem, String name) { String header = subsystem.getSubsystemHeaders(null).get(name); assertNotNull("Missing header: " + name, header); return header; } - + protected void assertId(Subsystem subsystem) { assertId(subsystem.getSubsystemId()); } - + protected void assertId(Long id) { assertTrue("Subsystem ID was not a positive integer: " + id, id > 0); } - + protected void assertLastId(long id) throws Exception { Subsystem root = getRootSubsystem(); Field lastId = SubsystemIdentifier.class.getDeclaredField("lastId"); lastId.setAccessible(true); assertEquals("Wrong lastId", id, lastId.getLong(root)); } - + protected void resetLastId() throws Exception { Field lastId = SubsystemIdentifier.class.getDeclaredField("lastId"); lastId.setAccessible(true); lastId.setInt(SubsystemIdentifier.class, 0); } - + protected void assertLocation(String expected, String actual) { assertTrue("Wrong location: " + actual, actual.indexOf(expected) != -1); } - + protected void assertLocation(String expected, Subsystem subsystem) { assertLocation(expected, subsystem.getLocation()); } - + protected void assertNotChild(Subsystem parent, Subsystem child) { assertFalse("Parent contained child", parent.getChildren().contains(child)); } - + protected void assertNotConstituent(Subsystem subsystem, String symbolicName) { assertNotConstituent(subsystem, symbolicName, Version.emptyVersion, IdentityNamespace.TYPE_BUNDLE); } - + protected void assertNotConstituent(Subsystem subsystem, String symbolicName, Version version, String type) { Resource constituent = getConstituent(subsystem, symbolicName, version, type); assertNull("Constituent found: " + symbolicName + ';' + version + ';' + type, constituent); } - + protected void assertParent(Subsystem expected, Subsystem subsystem) { for (Subsystem parent : subsystem.getParents()) { if (parent.equals(expected)) return; - + } fail("Parent did not exist: " + expected.getSymbolicName()); } - + protected void assertProvisionPolicy(Subsystem subsystem, boolean acceptsDependencies) { String headerStr = subsystem.getSubsystemHeaders(null).get(SubsystemConstants.SUBSYSTEM_TYPE); assertNotNull("Missing subsystem type header", headerStr); @@ -461,7 +375,7 @@ public abstract class SubsystemTest exte else assertTrue("Subsystem accepts dependencies", directive.isRejectDependencies()); } - + protected void assertRefresh(Collection<Bundle> bundles) throws InterruptedException { FrameworkWiring wiring = getSystemBundleAsFrameworkWiring(); final AtomicBoolean refreshed = new AtomicBoolean(false); @@ -481,12 +395,12 @@ public abstract class SubsystemTest exte } assertTrue("Bundles not refreshed", refreshed.get()); } - + protected void assertRefreshAndResolve(Collection<Bundle> bundles) throws InterruptedException { assertRefresh(bundles); assertResolve(bundles); } - + protected void assertRegionContextBundle(Subsystem s) { Bundle b = getRegionContextBundle(s); assertEquals("Not active", Bundle.ACTIVE, b.getState()); @@ -495,59 +409,59 @@ public abstract class SubsystemTest exte assertEquals("Wrong version", Version.parseVersion("1.0.0"), b.getVersion()); assertConstituent(s, "org.osgi.service.subsystem.region.context." + s.getSubsystemId(), Version.parseVersion("1.0.0"), IdentityNamespace.TYPE_BUNDLE); } - + protected void assertResolve(Collection<Bundle> bundles) { FrameworkWiring wiring = getSystemBundleAsFrameworkWiring(); assertTrue("Bundles not resolved", wiring.resolveBundles(bundles)); } - + protected void assertServiceEventsInstall(Subsystem subsystem) throws InterruptedException { assertEvent(subsystem, Subsystem.State.INSTALLING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000)); assertEvent(subsystem, Subsystem.State.INSTALLED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000)); } - + protected void assertServiceEventsResolve(Subsystem subsystem) throws InterruptedException { assertEvent(subsystem, Subsystem.State.RESOLVING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000)); assertServiceEventResolved(subsystem, ServiceEvent.MODIFIED); } - + protected void assertServiceEventsStart(Subsystem subsystem) throws InterruptedException { assertEvent(subsystem, Subsystem.State.STARTING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000)); assertEvent(subsystem, Subsystem.State.ACTIVE, subsystemEvents.poll(subsystem.getSubsystemId(), 5000)); } - + protected void assertServiceEventsStop(Subsystem subsystem) throws InterruptedException { assertEvent(subsystem, Subsystem.State.STOPPING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000)); assertServiceEventResolved(subsystem, ServiceEvent.MODIFIED); // Don't forget about the unregistering event, which will have the same state as before. assertServiceEventResolved(subsystem, ServiceEvent.UNREGISTERING); } - + protected void assertServiceEventResolved(Subsystem subsystem, int type) throws InterruptedException { assertEvent(subsystem, Subsystem.State.RESOLVED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000), type); } - + protected void assertStartLevel(Bundle bundle, int expected) { assertNotNull("Bundle is null", bundle); - assertEquals("Wrong start level", expected, ((BundleStartLevel) bundle.adapt(BundleStartLevel.class)).getStartLevel()); + assertEquals("Wrong start level", expected, bundle.adapt(BundleStartLevel.class).getStartLevel()); } - + protected void assertState(State expected, State actual) { assertState(EnumSet.of(expected), actual); } - + protected void assertState(EnumSet<State> expected, State actual) { assertTrue("Wrong state: expected=" + expected + ", actual=" + actual, expected.contains(actual)); } - + protected void assertState(State expected, Subsystem subsystem) { assertState(expected, subsystem.getState()); } - + protected void assertState(EnumSet<State> expected, Subsystem subsystem) { assertState(expected, subsystem.getState()); } - + protected Subsystem assertSubsystemLifeCycle(File file) throws Exception { Subsystem rootSubsystem = context().getService(Subsystem.class); assertNotNull("Root subsystem was null", rootSubsystem); @@ -574,47 +488,47 @@ public abstract class SubsystemTest exte assertNotChild(rootSubsystem, subsystem); return subsystem; } - + protected void assertSubsystemNotNull(Subsystem subsystem) { assertNotNull("Subsystem was null", subsystem); } - + protected void assertSymbolicName(String expected, Subsystem subsystem) { assertSymbolicName(expected, subsystem.getSymbolicName()); } - + protected void assertSymbolicName(String expected, String actual) { assertEquals("Wrong symbolic name", expected, actual); } - + protected void assertType(String expected, Subsystem subsystem) { assertEquals("Wrong type", expected, subsystem.getType()); } - + protected void assertVersion(String expected, Subsystem subsystem) { assertVersion(Version.parseVersion(expected), subsystem); } - + protected void assertVersion(Version expected, Subsystem subsystem) { assertVersion(expected, subsystem.getVersion()); } - + protected void assertVersion(Version expected, Version actual) { assertEquals("Wrong version", expected, actual); } - + protected Header version(String version) { return new Header(Constants.BUNDLE_VERSION, version); } - + protected Header name(String name) { return new Header(Constants.BUNDLE_SYMBOLICNAME, name); } - + protected Header exportPackage(String exportPackage) { return new Header(Constants.EXPORT_PACKAGE, exportPackage); } - + protected Header importPackage(String importPackage) { return new Header(Constants.IMPORT_PACKAGE, importPackage); } @@ -622,7 +536,7 @@ public abstract class SubsystemTest exte protected Header requireBundle(String bundleName) { return new Header(Constants.REQUIRE_BUNDLE, bundleName); } - + protected Header requireCapability(String capability) { return new Header(Constants.REQUIRE_CAPABILITY, capability); } @@ -641,8 +555,8 @@ public abstract class SubsystemTest exte } createBundle(emptyFiles, headerMap); } - - private static void createBundle(List<String> emptyFiles, Map<String, String> headers) throws IOException + + private static void createBundle(List<String> emptyFiles, Map<String, String> headers) throws IOException { String symbolicName = headers.get(Constants.BUNDLE_SYMBOLICNAME); JarFixture bundle = ArchiveFixture.newJar(); @@ -655,22 +569,22 @@ public abstract class SubsystemTest exte } write(symbolicName, bundle); } - + protected static void createBlueprintBundle(String symbolicName, String blueprintXml) throws IOException { write(symbolicName, ArchiveFixture.newJar().manifest().symbolicName(symbolicName) .end().file("OSGI-INF/blueprint/blueprint.xml", blueprintXml)); } - + protected Resource createBundleRepositoryContent(String file) throws Exception { return createBundleRepositoryContent(new File(file)); } - + protected Resource createBundleRepositoryContent(File file) throws Exception { return new BundleResource(FileSystem.getFSRoot(file)); } - + protected static void createManifest(String name, Map<String, String> headers) throws IOException { ManifestFixture manifest = ArchiveFixture.newJar().manifest(); for (Entry<String, String> header : headers.entrySet()) { @@ -678,7 +592,7 @@ public abstract class SubsystemTest exte } write(name, manifest); } - + protected static void createSubsystem(String name, String...contents) throws IOException { File manifest = new File(name + ".mf"); ZipFixture fixture = ArchiveFixture.newZip(); @@ -693,20 +607,20 @@ public abstract class SubsystemTest exte } write(name, fixture); } - + protected Subsystem findSubsystemService(long id) throws InvalidSyntaxException { String filter = "(" + SubsystemConstants.SUBSYSTEM_ID_PROPERTY + "=" + id + ")"; return context().getService(Subsystem.class, filter, 5000); } - + protected Subsystem getChild(Subsystem parent, String symbolicName) { return getChild(parent, symbolicName, null, null); } - + protected Subsystem getChild(Subsystem parent, String symbolicName, Version version) { return getChild(parent, symbolicName, version, null); } - + protected Subsystem getChild(Subsystem parent, String symbolicName, Version version, String type) { for (Subsystem child : parent.getChildren()) { if (symbolicName.equals(child.getSymbolicName())) { @@ -723,16 +637,40 @@ public abstract class SubsystemTest exte } return null; } - - protected Resource getConstituent(Subsystem subsystem, String symbolicName, Version version, String type) { + + public static Object getIdentityAttribute(Resource resource, String name) { + List<Capability> capabilities = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE); + Capability capability = capabilities.get(0); + return capability.getAttributes().get(name); + } + + public static String getSymbolicNameAttribute(Resource resource) { + return (String)getIdentityAttribute(resource, IdentityNamespace.IDENTITY_NAMESPACE); + } + + public static Version getVersionAttribute(Resource resource) { + Version result = (Version)getIdentityAttribute(resource, IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE); + if (result == null) + result = Version.emptyVersion; + return result; + } + + public static String getTypeAttribute(Resource resource) { + String result = (String)getIdentityAttribute(resource, IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE); + if (result == null) + result = TypeAttribute.DEFAULT_VALUE; + return result; + } + + protected Resource getConstituent(Subsystem subsystem, String symbolicName, Version version, String type) { for (Resource resource : subsystem.getConstituents()) { - if (symbolicName.equals(ResourceHelper.getSymbolicNameAttribute(resource))) { + if (symbolicName.equals(getSymbolicNameAttribute(resource))) { if (version == null) version = Version.emptyVersion; - if (version.equals(ResourceHelper.getVersionAttribute(resource))) { + if (version.equals(getVersionAttribute(resource))) { if (type == null) type = IdentityNamespace.TYPE_BUNDLE; - if (type.equals(ResourceHelper.getTypeAttribute(resource))) { + if (type.equals(getTypeAttribute(resource))) { return resource; } } @@ -740,26 +678,26 @@ public abstract class SubsystemTest exte } return null; } - + protected AriesSubsystem getConstituentAsAriesSubsystem(Subsystem subsystem, String symbolicName, Version version, String type) { Resource resource = getConstituent(subsystem, symbolicName, version, type); return (AriesSubsystem)resource; } - + protected Bundle getConstituentAsBundle(Subsystem subsystem, String symbolicName, Version version, String type) { return getConstituentAsBundleRevision(subsystem, symbolicName, version, type).getBundle(); } - + protected BundleRevision getConstituentAsBundleRevision(Subsystem subsystem, String symbolicName, Version version, String type) { Resource resource = getConstituent(subsystem, symbolicName, version, type); return (BundleRevision)resource; } - + protected Subsystem getConstituentAsSubsystem(Subsystem subsystem, String symbolicName, Version version, String type) { Resource resource = getConstituent(subsystem, symbolicName, version, type); return (Subsystem)resource; } - + protected Region getRegion(Subsystem subsystem) { RegionDigraph digraph = context().getService(RegionDigraph.class); String name = getRegionName(subsystem); @@ -767,27 +705,27 @@ public abstract class SubsystemTest exte assertNotNull("Region not found: " + name, region); return region; } - + protected Bundle getRegionContextBundle(Subsystem subsystem) { BundleContext bc = subsystem.getBundleContext(); assertNotNull("No region context bundle", bc); return bc.getBundle(); } - + protected String getRegionName(Subsystem subsystem) { if (subsystem.getSubsystemId() == 0) return "org.eclipse.equinox.region.kernel"; return subsystem.getSymbolicName() + ';' + subsystem.getVersion() + ';' + subsystem.getType() + ';' + subsystem.getSubsystemId(); } - + protected AriesSubsystem getRootAriesSubsystem() { return context().getService(AriesSubsystem.class); } - + protected Subsystem getRootSubsystem() { return context().getService(Subsystem.class, "(subsystem.id=0)"); } - + protected Subsystem getRootSubsystemInState(Subsystem.State state, long timeout) throws InterruptedException { Subsystem root = getRootSubsystem(); long now = System.currentTimeMillis(); @@ -798,71 +736,71 @@ public abstract class SubsystemTest exte fail("Root subsystem never achieved state: " + state); return root; } - + protected Bundle getSystemBundle() { return bundleContext.getBundle(Constants.SYSTEM_BUNDLE_LOCATION); } - + protected FrameworkStartLevel getSystemBundleAsFrameworkStartLevel() { - return (FrameworkStartLevel) getSystemBundle().adapt(FrameworkStartLevel.class); + return getSystemBundle().adapt(FrameworkStartLevel.class); } - + protected FrameworkWiring getSystemBundleAsFrameworkWiring() { - return (FrameworkWiring) getSystemBundle().adapt(FrameworkWiring.class); + return getSystemBundle().adapt(FrameworkWiring.class); } - + protected Bundle getSubsystemCoreBundle() { - return context().getBundleByName("org.apache.aries.subsystem.core"); + return context().getBundleByName(SUBSYSTEM_CORE_NAME); } - + protected Bundle installBundleFromFile(String fileName) throws FileNotFoundException, BundleException { return installBundleFromFile(new File(fileName), getRootSubsystem()); } - + protected Bundle installBundleFromFile(String fileName, Subsystem subsystem) throws FileNotFoundException, BundleException { return installBundleFromFile(new File(fileName), subsystem); } - + private Bundle installBundleFromFile(File file, Subsystem subsystem) throws FileNotFoundException, BundleException { Bundle bundle = installBundleFromFile(file, subsystem.getBundleContext()); assertBundleState(Bundle.INSTALLED|Bundle.RESOLVED, bundle.getSymbolicName(), subsystem); return bundle; } - + private Bundle installBundleFromFile(File file, BundleContext bundleContext) throws FileNotFoundException, BundleException { // The following input stream is closed by the bundle context. return bundleContext.installBundle(file.toURI().toString(), new FileInputStream(file)); } - + protected Subsystem installSubsystemFromFile(Subsystem parent, String fileName) throws Exception { return installSubsystemFromFile(parent, new File(fileName)); } - + protected Subsystem installSubsystemFromFile(String fileName) throws Exception { return installSubsystemFromFile(new File(fileName)); } - + protected Subsystem installSubsystemFromFile(Subsystem parent, File file) throws Exception { return installSubsystem(parent, file.toURI().toURL().toExternalForm()); } - + private Subsystem installSubsystemFromFile(File file) throws Exception { return installSubsystem(getRootSubsystem(), file.toURI().toURL().toExternalForm()); } - + protected Subsystem installSubsystem(String location) throws Exception { return installSubsystem(getRootSubsystem(), location); } - + protected Subsystem installSubsystem(String location, InputStream content) throws Exception { return installSubsystem(getRootSubsystem(), location, content); } - + protected Subsystem installSubsystem(Subsystem parent, String location) throws Exception { // The following input stream is closed by Subsystem.install. return installSubsystem(parent, location, new URL(location).openStream()); } - + protected Subsystem installSubsystem(Subsystem parent, String location, InputStream content) throws Exception { subsystemEvents.clear(); Subsystem subsystem = parent.install(location, content); @@ -879,12 +817,12 @@ public abstract class SubsystemTest exte // assertDirectory(subsystem); return subsystem; } - + protected void registerRepositoryService(Repository repository) { serviceRegistrations.add(bundleContext.registerService( Repository.class, repository, null)); } - + protected void registerRepositoryService(Resource...resources) { TestRepository.Builder builder = new TestRepository.Builder(); for (Resource resource : resources) { @@ -892,7 +830,7 @@ public abstract class SubsystemTest exte } registerRepositoryService(builder.build()); } - + protected void registerRepositoryService(String...files) throws Exception { Resource[] resources = new Resource[files.length]; int i = 0; @@ -901,26 +839,26 @@ public abstract class SubsystemTest exte } registerRepositoryService(resources); } - + protected void restartSubsystemsImplBundle() throws BundleException { Bundle b = getSubsystemCoreBundle(); b.stop(); b.start(); } - + protected void startBundle(Bundle bundle) throws BundleException { startBundle(bundle, getRootSubsystem()); } - + protected void startBundle(Bundle bundle, Subsystem subsystem) throws BundleException { bundle.start(); assertBundleState(Bundle.ACTIVE, bundle.getSymbolicName(), subsystem); } - + protected void startSubsystem(Subsystem subsystem) throws Exception { startSubsystemFromInstalled(subsystem); } - + protected void startSubsystemFromInstalled(Subsystem subsystem) throws InterruptedException { assertState(State.INSTALLED, subsystem); subsystemEvents.clear(); @@ -931,7 +869,7 @@ public abstract class SubsystemTest exte assertEvent(subsystem, State.ACTIVE, 5000); assertState(State.ACTIVE, subsystem); } - + protected void startSubsystemFromResolved(Subsystem subsystem) throws InterruptedException { assertState(State.RESOLVED, subsystem); subsystemEvents.clear(); @@ -940,12 +878,12 @@ public abstract class SubsystemTest exte assertEvent(subsystem, State.ACTIVE, 5000); assertState(State.ACTIVE, subsystem); } - + protected void stopAndUninstallSubsystemSilently(Subsystem subsystem) { stopSubsystemSilently(subsystem); uninstallSubsystemSilently(subsystem); } - + protected void stopSubsystem(Subsystem subsystem) throws Exception { assertState(State.ACTIVE, subsystem); subsystemEvents.clear(); @@ -954,7 +892,7 @@ public abstract class SubsystemTest exte assertEvent(subsystem, State.RESOLVED, 5000); assertState(State.RESOLVED, subsystem); } - + protected void stopSubsystemSilently(Subsystem subsystem) { try { stopSubsystem(subsystem); @@ -963,7 +901,7 @@ public abstract class SubsystemTest exte t.printStackTrace(); } } - + protected void uninstallSilently(Bundle bundle) { if (bundle == null) return; @@ -972,7 +910,7 @@ public abstract class SubsystemTest exte } catch (Exception e) {} } - + protected void uninstallSubsystem(Subsystem subsystem) throws Exception { assertState(EnumSet.of(State.INSTALLED, State.RESOLVED), subsystem); subsystemEvents.clear(); @@ -1001,7 +939,7 @@ public abstract class SubsystemTest exte assertNull("Region not removed", digraph.getRegion(region.getName())); } } - + protected void uninstallSubsystemSilently(Subsystem subsystem) { if (subsystem == null) return; @@ -1012,12 +950,21 @@ public abstract class SubsystemTest exte t.printStackTrace(); } } - - protected static void write(String file, ArchiveFixture.AbstractFixture fixture) throws IOException + + protected void writeToFile(InputStream is, String name) { + try { + FileOutputStream dest = new FileOutputStream(name); + StreamUtils.copyStream(is, dest, true); + } catch (IOException e) { + e.printStackTrace(); + } + } + + protected static void write(String file, ArchiveFixture.AbstractFixture fixture) throws IOException { write(new File(file), fixture); } - + private static void write(File file, ArchiveFixture.AbstractFixture fixture) throws IOException { FileOutputStream fos = new FileOutputStream(file); try { @@ -1027,25 +974,24 @@ public abstract class SubsystemTest exte fos.close(); } } - - static void createApplication(String name, String ... content) throws Exception + + static void createApplication(String name, String ... contents) throws Exception { - ZipFixture feature = ArchiveFixture + ClassLoader cl = SubsystemTest.class.getClassLoader(); + ZipFixture feature = ArchiveFixture .newZip() .binary("OSGI-INF/SUBSYSTEM.MF", // The following input stream is closed by ArchiveFixture.copy. - SubsystemTest.class.getClassLoader().getResourceAsStream( - name + "/OSGI-INF/SUBSYSTEM.MF")); - for (String s : content) { + cl.getResourceAsStream(name + "/OSGI-INF/SUBSYSTEM.MF")); + for (String content : contents) { try { - feature.binary(s, + feature.binary(content, // The following input stream is closed by ArchiveFixture.copy. - SubsystemTest.class.getClassLoader().getResourceAsStream( - name + '/' + s)); + cl.getResourceAsStream(name + '/' + content)); } catch (Exception e) { // The following input stream is closed by ArchiveFixture.copy. - feature.binary(s, new FileInputStream(new File(s))); + feature.binary(content, new FileInputStream(new File(content))); } } feature.end(); @@ -1056,7 +1002,7 @@ public abstract class SubsystemTest exte Utils.closeQuietly(fos); } } - + protected static String normalizeBundleLocation(Bundle bundle) { return normalizeBundleLocation(bundle.getLocation()); } @@ -1066,80 +1012,13 @@ public abstract class SubsystemTest exte return location.substring(8); return location; } - - protected static final byte[] EMPTY_CLASS = new byte[] { - (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, - (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x32, - (byte)0x00, (byte)0x12, (byte)0x07, (byte)0x00, - (byte)0x02, (byte)0x01, (byte)0x00, (byte)0x05, - (byte)0x45, (byte)0x6d, (byte)0x70, (byte)0x74, - (byte)0x79, (byte)0x07, (byte)0x00, (byte)0x04, - (byte)0x01, (byte)0x00, (byte)0x10, (byte)0x6a, - (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, - (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, - (byte)0x2f, (byte)0x4f, (byte)0x62, (byte)0x6a, - (byte)0x65, (byte)0x63, (byte)0x74, (byte)0x07, - (byte)0x00, (byte)0x06, (byte)0x01, (byte)0x00, - (byte)0x14, (byte)0x6a, (byte)0x61, (byte)0x76, - (byte)0x61, (byte)0x2f, (byte)0x69, (byte)0x6f, - (byte)0x2f, (byte)0x53, (byte)0x65, (byte)0x72, - (byte)0x69, (byte)0x61, (byte)0x6c, (byte)0x69, - (byte)0x7a, (byte)0x61, (byte)0x62, (byte)0x6c, - (byte)0x65, (byte)0x01, (byte)0x00, (byte)0x06, - (byte)0x3c, (byte)0x69, (byte)0x6e, (byte)0x69, - (byte)0x74, (byte)0x3e, (byte)0x01, (byte)0x00, - (byte)0x03, (byte)0x28, (byte)0x29, (byte)0x56, - (byte)0x01, (byte)0x00, (byte)0x04, (byte)0x43, - (byte)0x6f, (byte)0x64, (byte)0x65, (byte)0x0a, - (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x0b, - (byte)0x0c, (byte)0x00, (byte)0x07, (byte)0x00, - (byte)0x08, (byte)0x01, (byte)0x00, (byte)0x0f, - (byte)0x4c, (byte)0x69, (byte)0x6e, (byte)0x65, - (byte)0x4e, (byte)0x75, (byte)0x6d, (byte)0x62, - (byte)0x65, (byte)0x72, (byte)0x54, (byte)0x61, - (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0x01, - (byte)0x00, (byte)0x12, (byte)0x4c, (byte)0x6f, - (byte)0x63, (byte)0x61, (byte)0x6c, (byte)0x56, - (byte)0x61, (byte)0x72, (byte)0x69, (byte)0x61, - (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0x54, - (byte)0x61, (byte)0x62, (byte)0x6c, (byte)0x65, - (byte)0x01, (byte)0x00, (byte)0x04, (byte)0x74, - (byte)0x68, (byte)0x69, (byte)0x73, (byte)0x01, - (byte)0x00, (byte)0x07, (byte)0x4c, (byte)0x45, - (byte)0x6d, (byte)0x70, (byte)0x74, (byte)0x79, - (byte)0x3b, (byte)0x01, (byte)0x00, (byte)0x0a, - (byte)0x53, (byte)0x6f, (byte)0x75, (byte)0x72, - (byte)0x63, (byte)0x65, (byte)0x46, (byte)0x69, - (byte)0x6c, (byte)0x65, (byte)0x01, (byte)0x00, - (byte)0x0a, (byte)0x45, (byte)0x6d, (byte)0x70, - (byte)0x74, (byte)0x79, (byte)0x2e, (byte)0x6a, - (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x00, - (byte)0x21, (byte)0x00, (byte)0x01, (byte)0x00, - (byte)0x03, (byte)0x00, (byte)0x01, (byte)0x00, - (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x00, - (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x00, - (byte)0x07, (byte)0x00, (byte)0x08, (byte)0x00, - (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00, - (byte)0x00, (byte)0x00, (byte)0x2f, (byte)0x00, - (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x00, - (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x2a, - (byte)0xb7, (byte)0x00, (byte)0x0a, (byte)0xb1, - (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, - (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x00, - (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x01, - (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04, - (byte)0x00, (byte)0x0d, (byte)0x00, (byte)0x00, - (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x01, - (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, - (byte)0x00, (byte)0x0e, (byte)0x00, (byte)0x0f, - (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, - (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, - (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x11 - }; - - protected static void createEmptyClass() throws IOException { - FileOutputStream fos = new FileOutputStream("Empty.class"); - fos.write(EMPTY_CLASS); - fos.close(); + + protected InputStream getResource(String path) { + InputStream is = this.getClass().getClassLoader().getResourceAsStream(path); + if (is == null) { + throw new IllegalArgumentException("No resource found at path " + path); + } + return is; } + } Modified: aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/resources/composite2/OSGI-INF/SUBSYSTEM.MF URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/resources/composite2/OSGI-INF/SUBSYSTEM.MF?rev=1650143&r1=1649881&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/resources/composite2/OSGI-INF/SUBSYSTEM.MF (original) +++ aries/branches/subsystemsR6/subsystem/subsystem-itests/src/test/resources/composite2/OSGI-INF/SUBSYSTEM.MF Wed Jan 7 19:37:42 2015 @@ -3,4 +3,4 @@ Subsystem-Type: osgi.subsystem.composite Subsystem-Content: org.apache.aries.subsystem.itests.tb4;version="[1.0.0,1.0.0]" Import-Package: org.osgi.framework,org.osgi.util.tracker Subsystem-ExportService: *;filter:="(test=tb4)" -Subsystem-ImportService: *;filter:="(test=testCompositeServiceImports)" \ No newline at end of file +Subsystem-ImportService: *;filter:="(test=testCompositeServiceImports)" Modified: aries/branches/subsystemsR6/subsystem/subsystem-obr/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/subsystem/subsystem-obr/pom.xml?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/subsystem/subsystem-obr/pom.xml (original) +++ aries/branches/subsystemsR6/subsystem/subsystem-obr/pom.xml Wed Jan 7 19:37:42 2015 @@ -45,7 +45,9 @@ <aries.osgi.activator> org.apache.aries.subsystem.obr.internal.Activator </aries.osgi.activator> - <aries.osgi.export.pkg/> + <aries.osgi.export.pkg> + org.apache.aries.subsystem.util.felix + </aries.osgi.export.pkg> <aries.osgi.private.pkg> org.apache.aries.subsystem.obr.internal </aries.osgi.private.pkg> Modified: aries/branches/subsystemsR6/subsystem/subsystem-obr/src/main/java/org/apache/aries/subsystem/obr/internal/RepositoryAdminRepository.java URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/subsystem/subsystem-obr/src/main/java/org/apache/aries/subsystem/obr/internal/RepositoryAdminRepository.java?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/subsystem/subsystem-obr/src/main/java/org/apache/aries/subsystem/obr/internal/RepositoryAdminRepository.java (original) +++ aries/branches/subsystemsR6/subsystem/subsystem-obr/src/main/java/org/apache/aries/subsystem/obr/internal/RepositoryAdminRepository.java Wed Jan 7 19:37:42 2015 @@ -23,6 +23,10 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.apache.aries.subsystem.util.felix.FelixCapabilityAdapter; +import org.apache.aries.subsystem.util.felix.FelixRepositoryAdapter; +import org.apache.aries.subsystem.util.felix.FelixResourceAdapter; +import org.apache.aries.subsystem.util.felix.OsgiRequirementAdapter; import org.apache.felix.bundlerepository.RepositoryAdmin; import org.apache.felix.bundlerepository.Resource; import org.osgi.framework.namespace.IdentityNamespace; Modified: aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/FelixCapabilityAdapterTest.java URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/FelixCapabilityAdapterTest.java?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/FelixCapabilityAdapterTest.java (original) +++ aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/FelixCapabilityAdapterTest.java Wed Jan 7 19:37:42 2015 @@ -18,6 +18,7 @@ import static org.junit.Assert.assertEqu import java.util.HashMap; import java.util.Map; +import org.apache.aries.subsystem.util.felix.FelixCapabilityAdapter; import org.apache.felix.bundlerepository.Capability; import org.apache.felix.bundlerepository.Resource; import org.easymock.EasyMock; Modified: aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/FelixRequirementAdapterTest.java URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/FelixRequirementAdapterTest.java?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/FelixRequirementAdapterTest.java (original) +++ aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/FelixRequirementAdapterTest.java Wed Jan 7 19:37:42 2015 @@ -15,6 +15,7 @@ package org.apache.aries.subsystem.obr.i import static org.junit.Assert.assertEquals; +import org.apache.aries.subsystem.util.felix.FelixRequirementAdapter; import org.apache.felix.bundlerepository.Requirement; import org.easymock.EasyMock; import org.junit.Test; Modified: aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/OsgiRequirementAdapterTest.java URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/OsgiRequirementAdapterTest.java?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/OsgiRequirementAdapterTest.java (original) +++ aries/branches/subsystemsR6/subsystem/subsystem-obr/src/test/java/org/apache/aries/subsystem/obr/internal/OsgiRequirementAdapterTest.java Wed Jan 7 19:37:42 2015 @@ -20,6 +20,7 @@ import static org.junit.Assert.assertTru import java.util.HashMap; import java.util.Map; +import org.apache.aries.subsystem.util.felix.OsgiRequirementAdapter; import org.apache.felix.bundlerepository.Capability; import org.easymock.EasyMock; import org.junit.Test; Modified: aries/branches/subsystemsR6/transaction/transaction-blueprint/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/transaction/transaction-blueprint/pom.xml?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/transaction/transaction-blueprint/pom.xml (original) +++ aries/branches/subsystemsR6/transaction/transaction-blueprint/pom.xml Wed Jan 7 19:37:42 2015 @@ -31,7 +31,7 @@ <groupId>org.apache.aries.transaction</groupId> <artifactId>org.apache.aries.transaction.blueprint</artifactId> <packaging>bundle</packaging> - <version>1.0.2-SNAPSHOT</version> + <version>1.0.3-SNAPSHOT</version> <name>Apache Aries Transaction Blueprint</name> <scm> @@ -113,6 +113,38 @@ </execution> </executions> </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>2.5.3</version> + <extensions>true</extensions> + <inherited>true</inherited> + <configuration> + <excludeDependencies>${aries.osgi.exclude.dependencies}</excludeDependencies> + <instructions> + <Bundle-Name>${project.name}</Bundle-Name> + <Bundle-SymbolicName>${aries.osgi.symbolic.name}</Bundle-SymbolicName> + <Bundle-Activator>${aries.osgi.activator}</Bundle-Activator> + <Export-Package>${aries.osgi.export}</Export-Package> + <Import-Package>${aries.osgi.import}</Import-Package> + <DynamicImport-Package>${aries.osgi.dynamic}</DynamicImport-Package> + <Private-Package>${aries.osgi.private.pkg}</Private-Package> + <Implementation-Title>Apache Aries</Implementation-Title> + <Implementation-Version>${project.version}</Implementation-Version> + <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor> + <Include-Resource>${aries.osgi.include.resource}</Include-Resource> + <_removeheaders>${aries.osgi.remove.headers}}</_removeheaders> + <_failok>${aries.osgi.failok}</_failok> + <_consumer-policy>${aries.osgi.import.default.version}</_consumer-policy> + <_provider-policy>$<range;[==,=+)></_provider-policy> + <Export-Service>${aries.osgi.export.service}</Export-Service> + <Import-Service>${aries.osgi.import.service}</Import-Service> + <Provide-Capability>${aries.osgi.provide.capability}</Provide-Capability> + <Require-Capability>${aries.osgi.require.capability}</Require-Capability> + <service_mode>generic</service_mode> + </instructions> + </configuration> + </plugin> </plugins> </build> Modified: aries/branches/subsystemsR6/transaction/transaction-itests/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/transaction/transaction-itests/pom.xml?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/transaction/transaction-itests/pom.xml (original) +++ aries/branches/subsystemsR6/transaction/transaction-itests/pom.xml Wed Jan 7 19:37:42 2015 @@ -66,19 +66,19 @@ <groupId>org.apache.aries.transaction</groupId> <artifactId>org.apache.aries.transaction.manager</artifactId> <scope>test</scope> - <version>1.1.1-SNAPSHOT</version> + <version>1.1.2-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.aries.transaction</groupId> <artifactId>org.apache.aries.transaction.blueprint</artifactId> <scope>test</scope> - <version>1.0.2-SNAPSHOT</version> + <version>1.0.3-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.aries.transaction</groupId> <artifactId>org.apache.aries.transaction.jdbc</artifactId> <scope>test</scope> - <version>2.1.0-SNAPSHOT</version> + <version>2.1.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.aries.transaction</groupId> Modified: aries/branches/subsystemsR6/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/AbstractIntegrationTest.java URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/AbstractIntegrationTest.java?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/AbstractIntegrationTest.java (original) +++ aries/branches/subsystemsR6/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/AbstractIntegrationTest.java Wed Jan 7 19:37:42 2015 @@ -64,6 +64,9 @@ public abstract class AbstractIntegratio mavenBundle("org.ops4j.pax.logging", "pax-logging-api"), mavenBundle("org.ops4j.pax.logging", "pax-logging-service"), mavenBundle("org.apache.geronimo.specs", "geronimo-jta_1.1_spec"), + mavenBundle("org.apache.geronimo.specs", "geronimo-j2ee-connector_1.6_spec"), + mavenBundle("org.apache.geronimo.specs", "geronimo-validation_1.0_spec"), + mavenBundle("org.apache.geronimo.components", "geronimo-connector"), mavenBundle("org.apache.derby", "derby"), mavenBundle("org.apache.aries", "org.apache.aries.util"), mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.api"), Modified: aries/branches/subsystemsR6/transaction/transaction-jdbc/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/transaction/transaction-jdbc/pom.xml?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/transaction/transaction-jdbc/pom.xml (original) +++ aries/branches/subsystemsR6/transaction/transaction-jdbc/pom.xml Wed Jan 7 19:37:42 2015 @@ -31,7 +31,7 @@ <groupId>org.apache.aries.transaction</groupId> <artifactId>org.apache.aries.transaction.jdbc</artifactId> <name>Apache Aries Transaction Enlisting JDBC Datasource</name> - <version>2.1.0-SNAPSHOT</version> + <version>2.1.1-SNAPSHOT</version> <packaging>bundle</packaging> <scm> @@ -42,19 +42,25 @@ <properties> <aries.osgi.export.pkg> - org.apache.aries.transaction.jdbc;-noimport:=true;version="2.0", - javax.resource*;version="1.6.0", + org.apache.aries.transaction.jdbc;-noimport:=true;version="2.1" </aries.osgi.export.pkg> <aries.osgi.import> - org.osgi.service.blueprint;resolution:=optional, - javax.validation;resolution:=optional, + org.osgi.service.blueprint.*;resolution:=optional, + org.apache.aries.transaction;version="[1.0,2)", + javax.resource.*;version="[1.6,3)", * </aries.osgi.import> <aries.osgi.private.pkg> org.apache.aries.transaction.jdbc.internal, - org.apache.geronimo.connector*, org.tranql*, </aries.osgi.private.pkg> + <aries.osgi.require.capability> + osgi.service; effective:=active; resolution:=optional; filter:="(objectClass=org.apache.aries.transaction.AriesTransactionManager)" + </aries.osgi.require.capability> + <aries.osgi.provide.capability> + osg.service; effective:=active; objectClass=org.apache.aries.blueprint.NamespaceHandler; osgi.service.blueprint.namespace="http://aries.apache.org/xmlns/transaction-jdbc/2.0", + osg.service; effective:=active; objectClass=org.apache.aries.blueprint.NamespaceHandler; osgi.service.blueprint.namespace="http://aries.apache.org/xmlns/transaction-jdbc/2.1" + </aries.osgi.provide.capability> <aries.osgi.activator> org.apache.aries.transaction.jdbc.internal.Activator </aries.osgi.activator> @@ -65,7 +71,7 @@ <dependency> <groupId>org.apache.aries.transaction</groupId> <artifactId>org.apache.aries.transaction.manager</artifactId> - <version>1.1.1-SNAPSHOT</version> + <version>1.1.1</version> </dependency> <dependency> <groupId>org.apache.aries</groupId> @@ -136,7 +142,30 @@ <goal>mapping</goal> </goals> <configuration> - <namespace>http://aries.apache.org/xmlns/transaction-jdbc/2.0</namespace> + <namespace>http://aries.apache.org/xmlns/transaction-jdbc/2.1</namespace> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.7</version> + <executions> + <execution> + <id>concat</id> + <goals> + <goal>run</goal> + </goals> + <phase>generate-resources</phase> + <configuration> + <target name="concat"> + <concat destfile="${basedir}/target/xbean/META-INF/spring.handlers" append="true"> + <filelist dir="${basedir}/src/main/resources/META-INF" files="spring.handlers" /> + </concat> + <concat destfile="${basedir}/target/xbean/META-INF/spring.schemas" append="true"> + <filelist dir="${basedir}/src/main/resources/META-INF" files="spring.schemas" /> + </concat> + </target> </configuration> </execution> </executions> @@ -154,6 +183,38 @@ </execution> </executions> </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>2.5.3</version> + <extensions>true</extensions> + <inherited>true</inherited> + <configuration> + <excludeDependencies>${aries.osgi.exclude.dependencies}</excludeDependencies> + <instructions> + <Bundle-Name>${project.name}</Bundle-Name> + <Bundle-SymbolicName>${aries.osgi.symbolic.name}</Bundle-SymbolicName> + <Bundle-Activator>${aries.osgi.activator}</Bundle-Activator> + <Export-Package>${aries.osgi.export}</Export-Package> + <Import-Package>${aries.osgi.import}</Import-Package> + <DynamicImport-Package>${aries.osgi.dynamic}</DynamicImport-Package> + <Private-Package>${aries.osgi.private.pkg}</Private-Package> + <Implementation-Title>Apache Aries</Implementation-Title> + <Implementation-Version>${project.version}</Implementation-Version> + <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor> + <Include-Resource>${aries.osgi.include.resource}</Include-Resource> + <_removeheaders>${aries.osgi.remove.headers}}</_removeheaders> + <_failok>${aries.osgi.failok}</_failok> + <_consumer-policy>${aries.osgi.import.default.version}</_consumer-policy> + <_provider-policy>$<range;[==,=+)></_provider-policy> + <Export-Service>${aries.osgi.export.service}</Export-Service> + <Import-Service>${aries.osgi.import.service}</Import-Service> + <Provide-Capability>${aries.osgi.provide.capability}</Provide-Capability> + <Require-Capability>${aries.osgi.require.capability}</Require-Capability> + <service_mode>generic</service_mode> + </instructions> + </configuration> + </plugin> </plugins> </build> Modified: aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/RecoverableDataSource.java URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/RecoverableDataSource.java?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/RecoverableDataSource.java (original) +++ aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/RecoverableDataSource.java Wed Jan 7 19:37:42 2015 @@ -192,7 +192,13 @@ public class RecoverableDataSource imple */ public void start() throws Exception { AbstractMCFFactory mcf; - if (dataSource instanceof XADataSource) { + if (("xa".equals(transaction) || "local".equals(transaction)) && transactionManager == null) { + throw new IllegalArgumentException("xa or local transactions specified, but no TransactionManager set"); + } + if ("xa".equals(transaction) && !(dataSource instanceof XADataSource)) { + throw new IllegalArgumentException("xa transactions specified, but DataSource does not implement javax.sql.XADataSource"); + } + if ("xa".equals(transaction) || (transactionManager != null && dataSource instanceof XADataSource)) { mcf = new XADataSourceMCFFactory(); if (transaction == null) { transaction = "xa"; @@ -200,7 +206,7 @@ public class RecoverableDataSource imple } else if (dataSource instanceof DataSource) { mcf = new DataSourceMCFFactory(); if (transaction == null) { - transaction = "local"; + transaction = transactionManager != null ? "local" : "none"; } } else { throw new IllegalArgumentException("dataSource must be of type javax.sql.DataSource/XADataSource"); @@ -225,6 +231,7 @@ public class RecoverableDataSource imple cm.setBackgroundValidation(backgroundValidation); cm.setBackgroundValidationMilliseconds(backgroundValidationMilliseconds); cm.setTransaction(transaction); + cm.setName(name); cm.init(); delegate = (DataSource) mcf.getConnectionFactory().createConnectionFactory(cm.getConnectionManager()); Modified: aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/Activator.java URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/Activator.java?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/Activator.java (original) +++ aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/Activator.java Wed Jan 7 19:37:42 2015 @@ -20,12 +20,12 @@ package org.apache.aries.transaction.jdb import org.apache.aries.blueprint.NamespaceHandler; import org.apache.aries.transaction.AriesTransactionManager; +import org.apache.aries.util.tracker.SingleServiceTracker; import org.apache.xbean.blueprint.context.impl.XBeanNamespaceHandler; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; +import org.osgi.framework.Filter; import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceEvent; -import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.ServiceTracker; @@ -33,18 +33,21 @@ import org.osgi.util.tracker.ServiceTrac import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.transaction.TransactionManager; +import javax.sql.CommonDataSource; import java.util.Hashtable; -public class Activator implements BundleActivator, ServiceTrackerCustomizer, ServiceListener { + +public class Activator implements BundleActivator, + ServiceTrackerCustomizer<CommonDataSource, ManagedDataSourceFactory>, + SingleServiceTracker.SingleServiceListener +{ private static final Logger LOGGER = LoggerFactory.getLogger(Activator.class); - private AriesTransactionManager tm; - private ServiceTracker t; - private ServiceReference ref; + private ServiceTracker<CommonDataSource, ManagedDataSourceFactory> t; + private SingleServiceTracker<AriesTransactionManager> tm; private BundleContext context; - private ServiceRegistration nshReg; + private ServiceRegistration[] nshReg; public void start(BundleContext ctx) { context = ctx; @@ -58,76 +61,59 @@ public class Activator implements Bundle LOGGER.error("Unable to register JDBC blueprint namespace handler", e); } - t = new ServiceTracker(ctx, javax.sql.XADataSource.class.getName(), this); - + Filter filter; + String flt = "(&(|(objectClass=javax.sql.XADataSource)(objectClass=javax.sql.DataSource))(!(aries.managed=true)))"; try { - ctx.addServiceListener(this, "(objectClass=" + AriesTransactionManager.class.getName() + ")"); + filter = context.createFilter(flt); } catch (InvalidSyntaxException e) { + throw new IllegalStateException(e); } - ref = ctx.getServiceReference(TransactionManager.class.getName()); - if (ref != null) { - tm = (AriesTransactionManager) ctx.getService(ref); - } + t = new ServiceTracker<CommonDataSource, ManagedDataSourceFactory>(ctx, filter, this); - if (tm != null) { - t.open(); - } + tm = new SingleServiceTracker<AriesTransactionManager>(ctx, AriesTransactionManager.class, this); + tm.open(); } public void stop(BundleContext ctx) { - // it is possible these are not cleaned by serviceChanged method when the - // tm service is still active - if (t != null) { - t.close(); - } - if (ref != null) { - context.ungetService(ref); - } + tm.close(); + t.close(); if (nshReg != null) { - nshReg.unregister(); + for (ServiceRegistration reg : nshReg) { + safeUnregisterService(reg); + } } } - public Object addingService(ServiceReference ref) { + public ManagedDataSourceFactory addingService(ServiceReference<CommonDataSource> ref) { try { - LOGGER.info("Wrapping XADataSource " + ref); - ManagedDataSourceFactory mdsf = new ManagedDataSourceFactory(ref, tm); - return mdsf.register(); + LOGGER.info("Wrapping DataSource " + ref); + ManagedDataSourceFactory mdsf = new ManagedDataSourceFactory(ref, tm.getService()); + mdsf.register(); + return mdsf; } catch (Exception e) { - LOGGER.warn("Error wrapping XADataSource " + ref, e); + LOGGER.warn("Error wrapping DataSource " + ref, e); return null; } } - public void modifiedService(ServiceReference ref, Object service) { - ServiceRegistration reg = (ServiceRegistration) service; - - Hashtable<String, Object> map = new Hashtable<String, Object>(); - for (String key : ref.getPropertyKeys()) { - map.put(key, ref.getProperty(key)); + public void modifiedService(ServiceReference<CommonDataSource> ref, ManagedDataSourceFactory service) { + try { + service.unregister(); + } catch (Exception e) { + LOGGER.warn("Error closing DataSource " + ref, e); + } + try { + service.register(); + } catch (Exception e) { + LOGGER.warn("Error wrapping DataSource " + ref, e); } - map.put("aries.xa.aware", "true"); - - reg.setProperties(map); - } - - public void removedService(ServiceReference ref, Object service) { - safeUnregisterService((ServiceRegistration) service); } - public void serviceChanged(ServiceEvent event) { - if (event.getType() == ServiceEvent.REGISTERED && tm == null) { - ref = event.getServiceReference(); - tm = (AriesTransactionManager) context.getService(ref); - - if (tm == null) ref = null; - else t.open(); - } else if (event.getType() == ServiceEvent.UNREGISTERING && tm != null && - ref.getProperty("service.id").equals(event.getServiceReference().getProperty("service.id"))) { - t.close(); - context.ungetService(ref); - ref = null; - tm = null; + public void removedService(ServiceReference<CommonDataSource> ref, ManagedDataSourceFactory service) { + try { + service.unregister(); + } catch (Exception e) { + LOGGER.warn("Error closing DataSource " + ref, e); } } @@ -141,18 +127,49 @@ public class Activator implements Bundle } } + @Override + public void serviceFound() + { + t.open(); + } + + @Override + public void serviceLost() + { + t.close(); + } + + @Override + public void serviceReplaced() + { + t.close(); + t.open(); + } + static class JdbcNamespaceHandler { - public static ServiceRegistration register(BundleContext context) throws Exception { - XBeanNamespaceHandler nsh = new XBeanNamespaceHandler( + public static ServiceRegistration[] register(BundleContext context) throws Exception { + XBeanNamespaceHandler nsh20 = new XBeanNamespaceHandler( "http://aries.apache.org/xmlns/transaction-jdbc/2.0", - "org.apache.aries.transaction.jdbc.xsd", + "org.apache.aries.transaction.jdbc-2.0.xsd", context.getBundle(), "META-INF/services/org/apache/xbean/spring/http/aries.apache.org/xmlns/transaction-jdbc/2.0" ); - Hashtable<String, Object> props = new Hashtable<String, Object>(); - props.put("osgi.service.blueprint.namespace", "http://aries.apache.org/xmlns/transaction-jdbc/2.0"); - return context.registerService(NamespaceHandler.class.getName(), nsh, props); + Hashtable<String, Object> props20 = new Hashtable<String, Object>(); + props20.put("osgi.service.blueprint.namespace", "http://aries.apache.org/xmlns/transaction-jdbc/2.0"); + ServiceRegistration reg20 = context.registerService(NamespaceHandler.class.getName(), nsh20, props20); + + XBeanNamespaceHandler nsh21 = new XBeanNamespaceHandler( + "http://aries.apache.org/xmlns/transaction-jdbc/2.1", + "org.apache.aries.transaction.jdbc.xsd", + context.getBundle(), + "META-INF/services/org/apache/xbean/spring/http/aries.apache.org/xmlns/transaction-jdbc/2.1" + ); + Hashtable<String, Object> props21 = new Hashtable<String, Object>(); + props21.put("osgi.service.blueprint.namespace", "http://aries.apache.org/xmlns/transaction-jdbc/2.1"); + ServiceRegistration reg21 = context.registerService(NamespaceHandler.class.getName(), nsh21, props21); + + return new ServiceRegistration[] { reg20, reg21 }; } } Modified: aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/ConnectionManagerFactory.java URL: http://svn.apache.org/viewvc/aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/ConnectionManagerFactory.java?rev=1650143&r1=1650142&r2=1650143&view=diff ============================================================================== --- aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/ConnectionManagerFactory.java (original) +++ aries/branches/subsystemsR6/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/ConnectionManagerFactory.java Wed Jan 7 19:37:42 2015 @@ -42,6 +42,8 @@ public class ConnectionManagerFactory { private AriesTransactionManager transactionManager; private ManagedConnectionFactory managedConnectionFactory; + private String name; + private TransactionSupport transactionSupport; private String transaction; @@ -69,7 +71,7 @@ public class ConnectionManagerFactory { } public void init() throws Exception { - if (transactionManager == null) { + if (transactionManager == null && ("xa".equals(transaction) || "local".equals(transaction))) { throw new IllegalArgumentException("transactionManager must be set"); } if (managedConnectionFactory == null) { @@ -78,7 +80,7 @@ public class ConnectionManagerFactory { // Apply the default value for property if necessary if (transactionSupport == null) { // No transaction - if (transaction == null || "local".equalsIgnoreCase(transaction)) { + if ("local".equalsIgnoreCase(transaction)) { transactionSupport = LocalTransactions.INSTANCE; } else if ("none".equalsIgnoreCase(transaction)) { transactionSupport = NoTransactions.INSTANCE; @@ -136,7 +138,7 @@ public class ConnectionManagerFactory { if (connectionTracker == null) { connectionTracker = new ConnectionTrackingCoordinator(); } - if (transactionManagerMonitor == null) { + if (transactionManagerMonitor == null && transactionManager != null) { transactionManagerMonitor = new GeronimoTransactionListener(connectionTracker); transactionManager.addTransactionAssociationListener(transactionManagerMonitor); } @@ -154,7 +156,7 @@ public class ConnectionManagerFactory { connectionTracker, transactionManager, managedConnectionFactory, - getClass().getName(), + name != null ? name : getClass().getName(), getClass().getClassLoader(), backgroundValidationMilliseconds); } else { @@ -166,7 +168,7 @@ public class ConnectionManagerFactory { connectionTracker, transactionManager, managedConnectionFactory, - getClass().getName(), + name != null ? name : getClass().getName(), getClass().getClassLoader()); } @@ -212,6 +214,14 @@ public class ConnectionManagerFactory { return transaction; } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + public void setTransaction(String transaction) { this.transaction = transaction; }
