Repository: activemq Updated Branches: refs/heads/activemq-5.11.x 78f53a13d -> b1d3801c7
[AMQ-5821] Use wiring to check for extensions This closes #119 Project: http://git-wip-us.apache.org/repos/asf/activemq/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/4d955658 Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/4d955658 Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/4d955658 Branch: refs/heads/activemq-5.11.x Commit: 4d955658d79806a0913985cc121189699a734b96 Parents: 78f53a1 Author: Christian Schneider <[email protected]> Authored: Tue Jun 23 14:54:06 2015 +0200 Committer: Daniel Kulp <[email protected]> Committed: Wed Jun 24 12:45:34 2015 -0400 ---------------------------------------------------------------------- .../apache/activemq/util/osgi/Activator.java | 77 +++++++++++++++----- 1 file changed, 58 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq/blob/4d955658/activemq-broker/src/main/java/org/apache/activemq/util/osgi/Activator.java ---------------------------------------------------------------------- diff --git a/activemq-broker/src/main/java/org/apache/activemq/util/osgi/Activator.java b/activemq-broker/src/main/java/org/apache/activemq/util/osgi/Activator.java index ea3729a..85c7c1c 100644 --- a/activemq-broker/src/main/java/org/apache/activemq/util/osgi/Activator.java +++ b/activemq-broker/src/main/java/org/apache/activemq/util/osgi/Activator.java @@ -16,13 +16,18 @@ */ package org.apache.activemq.util.osgi; +import static org.osgi.framework.wiring.BundleRevision.PACKAGE_NAMESPACE; + +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.BufferedReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Properties; -import java.util.ArrayList; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.net.URL; @@ -41,6 +46,9 @@ import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.SynchronousBundleListener; +import org.osgi.framework.wiring.BundleCapability; +import org.osgi.framework.wiring.BundleWire; +import org.osgi.framework.wiring.BundleWiring; /** * An OSGi bundle activator for ActiveMQ which adapts the {@link org.apache.activemq.util.FactoryFinder} @@ -51,9 +59,10 @@ public class Activator implements BundleActivator, SynchronousBundleListener, Ob private static final Logger LOG = LoggerFactory.getLogger(Activator.class); - private final ConcurrentHashMap<String, Class> serviceCache = new ConcurrentHashMap<String, Class>(); + private final ConcurrentMap<String, Class<?>> serviceCache = new ConcurrentHashMap<String, Class<?>>(); private final ConcurrentMap<Long, BundleWrapper> bundleWrappers = new ConcurrentHashMap<Long, BundleWrapper>(); private BundleContext bundleContext; + private Set<BundleCapability> packageCapabilities = new HashSet<BundleCapability>(); // ================================================================ // BundleActivator interface impl @@ -67,6 +76,9 @@ public class Activator implements BundleActivator, SynchronousBundleListener, Ob debug("activating"); this.bundleContext = bundleContext; + + cachePackageCapabilities(Service.class, Transport.class, DiscoveryAgent.class, PersistenceAdapter.class); + debug("checking existing bundles"); bundleContext.addBundleListener(this); for (Bundle bundle : bundleContext.getBundles()) { @@ -78,6 +90,27 @@ public class Activator implements BundleActivator, SynchronousBundleListener, Ob debug("activated"); } + /** + * Caches the package capabilities that are needed for a set of interface classes + * + * @param classes interfaces we want to track + */ + private void cachePackageCapabilities(Class<?> ... classes) { + BundleWiring ourWiring = bundleContext.getBundle().adapt(BundleWiring.class); + Set<String> packageNames = new HashSet<String>(); + for (Class<?> clazz: classes) { + packageNames.add(clazz.getPackage().getName()); + } + + List<BundleCapability> ourExports = ourWiring.getCapabilities(PACKAGE_NAMESPACE); + for (BundleCapability ourExport : ourExports) { + String ourPkgName = (String) ourExport.getAttributes().get(PACKAGE_NAMESPACE); + if (packageNames.contains(ourPkgName)) { + packageCapabilities.add(ourExport); + } + } + } + public synchronized void stop(BundleContext bundleContext) throws Exception { debug("deactivating"); @@ -103,11 +136,14 @@ public class Activator implements BundleActivator, SynchronousBundleListener, Ob protected void register(final Bundle bundle) { debug("checking bundle " + bundle.getBundleId()); - if( !isImportingUs(bundle) ) { - debug("The bundle does not import us: "+ bundle.getBundleId()); - return; + if (isOurBundle(bundle) || isImportingUs(bundle) ) { + debug("Registering bundle for extension resolution: "+ bundle.getBundleId()); + bundleWrappers.put(bundle.getBundleId(), new BundleWrapper(bundle)); } - bundleWrappers.put(bundle.getBundleId(), new BundleWrapper(bundle)); + } + + private boolean isOurBundle(final Bundle bundle) { + return bundle.getBundleId() == bundleContext.getBundle().getBundleId(); } /** @@ -134,7 +170,7 @@ public class Activator implements BundleActivator, SynchronousBundleListener, Ob // ================================================================ public Object create(String path) throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException { - Class clazz = serviceCache.get(path); + Class<?> clazz = serviceCache.get(path); if (clazz == null) { StringBuffer warnings = new StringBuffer(); // We need to look for a bundle that has that class. @@ -202,19 +238,22 @@ public class Activator implements BundleActivator, SynchronousBundleListener, Ob } } + /** + * We consider a bundle to be a candidate for objects if it imports at least + * one of the packages of our interfaces + * + * @param bundle + * @return + */ private boolean isImportingUs(Bundle bundle) { - return isImportingClass(bundle, Service.class) - || isImportingClass(bundle, Transport.class) - || isImportingClass(bundle, DiscoveryAgent.class) - || isImportingClass(bundle, PersistenceAdapter.class); - } - - private boolean isImportingClass(Bundle bundle, Class clazz) { - try { - return bundle.loadClass(clazz.getName())==clazz; - } catch (ClassNotFoundException e) { - return false; + BundleWiring wiring = bundle.adapt(BundleWiring.class); + List<BundleWire> imports = wiring.getRequiredWires(PACKAGE_NAMESPACE); + for (BundleWire importWire : imports) { + if (packageCapabilities.contains(importWire.getCapability())) { + return true; + } } + return false; } private static class BundleWrapper {
