mirror of https://github.com/apache/activemq.git
parent
f0cb95c792
commit
97cd60fb7e
|
@ -16,14 +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.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
|
@ -38,6 +42,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;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -50,9 +57,10 @@ public class Activator implements BundleActivator, SynchronousBundleListener, Ob
|
|||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
|
||||
|
||||
private final ConcurrentMap<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 +75,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 +89,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void stop(BundleContext bundleContext) throws Exception {
|
||||
|
@ -105,12 +137,15 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOurBundle(final Bundle bundle) {
|
||||
return bundle.getBundleId() == bundleContext.getBundle().getBundleId();
|
||||
}
|
||||
|
||||
/**
|
||||
* When bundles unload.. we remove them thier cached Class entries from the
|
||||
|
@ -137,7 +172,7 @@ public class Activator implements BundleActivator, SynchronousBundleListener, Ob
|
|||
|
||||
@Override
|
||||
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.
|
||||
|
@ -205,20 +240,23 @@ 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);
|
||||
BundleWiring wiring = bundle.adapt(BundleWiring.class);
|
||||
List<BundleWire> imports = wiring.getRequiredWires(PACKAGE_NAMESPACE);
|
||||
for (BundleWire importWire : imports) {
|
||||
if (packageCapabilities.contains(importWire.getCapability())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isImportingClass(Bundle bundle, Class clazz) {
|
||||
try {
|
||||
return bundle.loadClass(clazz.getName())==clazz;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class BundleWrapper {
|
||||
private final Bundle bundle;
|
||||
|
|
Loading…
Reference in New Issue