You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by jw...@apache.org on 2013/01/07 16:05:40 UTC
svn commit: r1429829 -
/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java
Author: jwross
Date: Mon Jan 7 15:05:40 2013
New Revision: 1429829
URL: http://svn.apache.org/viewvc?rev=1429829&view=rev
Log:
[ARIES-996] JPA does not work for bundles that are constituents of subsystems.
A bundle tracker was added to track the region context bundles of subsystems. When a context is registered, these bundles are
examined to see if one is visible to the client bundle. If so, that region context bundle is used to establish the relationship
with a persistence context manager. If no subsystem region context bundles are present, the behavior is the same as before.
Composite bundle frameworks are still supported as well.
Modified:
aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java
Modified: aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java
URL: http://svn.apache.org/viewvc/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java?rev=1429829&r1=1429828&r2=1429829&view=diff
==============================================================================
--- aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java (original)
+++ aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/impl/GlobalPersistenceManager.java Mon Jan 7 15:05:40 2013
@@ -23,8 +23,8 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
-import java.util.Set;
import java.util.Map.Entry;
+import java.util.Set;
import org.apache.aries.jpa.container.context.JTAPersistenceContextManager;
import org.apache.aries.jpa.container.context.PersistenceContextProvider;
@@ -37,6 +37,8 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.util.tracker.BundleTracker;
+import org.osgi.util.tracker.BundleTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -76,6 +78,10 @@ public class GlobalPersistenceManager im
private ServiceRegistration pcpReg;
/** Our bundle */
private Bundle bundle;
+
+ // Used to track the the region context bundles provided by subsystems so the
+ // appropriate persistence context manager relationships are maintained.
+ private BundleTracker subsystemContextBundleTracker;
public void registerContext(String unitName, Bundle client, HashMap<String, Object> properties) {
if (_logger.isDebugEnabled()) {
@@ -87,7 +93,7 @@ public class GlobalPersistenceManager im
_logger.warn(NLS.MESSAGES.getMessage("no.tran.manager.for.bundle", unitName, client.getSymbolicName(), client.getVersion()));
//Find the framework for this bundle (we may be in a composite)
- Bundle frameworkBundle = client.getBundleContext().getBundle(0);
+ Bundle frameworkBundle = findFrameworkBundle(client);
PersistenceContextManager manager = null;
boolean newManager = false;
@@ -132,7 +138,7 @@ public class GlobalPersistenceManager im
//We only care about bundles stopping
if (event.getType() == BundleEvent.STOPPING) {
Set<String> contextsToBeRemoved = new HashSet<String>();
- Bundle frameworkBundle = bundle.getBundleContext().getBundle(0);
+ Bundle frameworkBundle = findFrameworkBundle(bundle);
PersistenceContextManager manager = null;
boolean removeManager = false;
@@ -240,6 +246,11 @@ public class GlobalPersistenceManager im
bundle = context.getBundle();
registry = new JTAPersistenceContextRegistry(context);
+ // Create and open the subsystem bundle context tracker before registering
+ // as a PersistenceContextProvider service.
+ subsystemContextBundleTracker = createSubsystemContextBundleTracker();
+ subsystemContextBundleTracker.open();
+
//Register our service
pcpReg = context.registerService(PersistenceContextProvider.class.getName(), this, null);
registryReg = context.registerService(JTAPersistenceContextManager.class.getName(), registry, null);
@@ -269,10 +280,68 @@ public class GlobalPersistenceManager im
for(PersistenceContextManager mgr : mgrs)
mgr.close();
+ subsystemContextBundleTracker.close();
+
registry.close();
}
public Bundle getBundle() {
return bundle;
}
+
+ private BundleTracker createSubsystemContextBundleTracker() {
+ BundleContext context = getSystemBundleContext();
+ BundleTrackerCustomizer customizer = createSubsystemContextBundleTrackerCustomizer();
+ return new BundleTracker(context, Bundle.ACTIVE, customizer);
+ }
+
+ private BundleContext getSystemBundleContext() {
+ // This assumes the JPA bundle has visibility to the system bundle, which
+ // may not be true. Ideally the system bundle should be gotten by
+ // location, but the method is not available in the OSGi version used by
+ // JPA.
+ return bundle.getBundleContext().getBundle(0).getBundleContext();
+ }
+
+ private BundleTrackerCustomizer createSubsystemContextBundleTrackerCustomizer() {
+ // Assume only the ACTIVE state is being tracked.
+ return new BundleTrackerCustomizer() {
+ public Bundle addingBundle(Bundle bundle, BundleEvent event) {
+ // Only track the region context bundles of subsystems.
+ if (bundle.getSymbolicName().startsWith("org.osgi.service.subsystem.region.context."))
+ return bundle;
+ return null;
+ }
+
+ public void modifiedBundle(Bundle bundle, BundleEvent event,
+ Object object) {
+ // Nothing.
+ }
+
+ public void removedBundle(Bundle bundle, BundleEvent event,
+ Object object) {
+ // Nothing.
+ }
+ };
+ }
+
+ /*
+ * Find the bundle with which to associate the persistence context manager.
+ * For subsystems, this will be the region context bundle of the subsystem of
+ * which the client is a constituent (which might be the root subsystem in
+ * which case the system bundle of the framework is returned). For composite
+ * bundles, this will be the system bundle of the composite bundle framework.
+ * Otherwise, this will be the system bundle of the framework.
+ */
+ private Bundle findFrameworkBundle(Bundle client) {
+ BundleContext clientBundleContext = client.getBundleContext();
+ Bundle[] tracked = subsystemContextBundleTracker.getBundles();
+ if (tracked != null)
+ for (Object subsystemContextBundle : tracked)
+ if (clientBundleContext.getBundle(((Bundle)subsystemContextBundle).getBundleId()) != null)
+ // If the subsystem context bundle is visible to the client bundle,
+ // then the client is a constituent of the subsystem.
+ return (Bundle)subsystemContextBundle;
+ return clientBundleContext.getBundle(0);
+ }
}