package org.foo.hub.extender;
import java.lang.reflect.Constructor;
import java.util.*;
import org.foo.hub.Message;
import org.foo.hub.api.Hub;
import org.foo.hub.spi.Spoke;
import org.osgi.framework.*;
/**
* Message hub that uses the OSGi extender pattern to attach spokes.
* (Assumes one spoke per-bundle and one message hub per-framework.)
*/
public class Activator implements BundleActivator, Hub {
BundleTracker spokeTracker;
Map<Bundle, Spoke> spokes = new HashMap<Bundle, Spoke>();
public void start(final BundleContext ctx) {
spokeTracker = new BundleTracker(ctx) {
public void addedBundle(Bundle bundle) {
Dictionary headers = bundle.getHeaders();
// we're only interested in bundles which have spokes
String clazzName = (String) headers.get("Spoke-Class");
String spokeName = (String) headers.get("Spoke-Name");
if (clazzName != null && spokeName != null) {
try {
System.out.println("START ADDING SPOKE " + spokeName);
// load the spoke class using the bundle's own ClassLoader
Constructor ctor = bundle.loadClass(clazzName).getConstructor(String.class);
spokes.put(bundle, (Spoke) ctor.newInstance(spokeName));
} catch (Throwable e) {
e.printStackTrace();
} finally {
System.out.println("DONE ADDING SPOKE " + spokeName);
}
}
}
public void removedBundle(Bundle bundle) {
spokes.remove(bundle);
}
};
spokeTracker.open();
ctx.registerService(Hub.class.getName(), this, null);
}
public int send(Message message) {
int count = 0;
// broadcast message to all spokes
for (Spoke s : spokes.values()) {
if (s.receive(message)) {
count++; // matching address
}
}
return count;
}
public void stop(BundleContext ctx) {
spokeTracker.close();
spokeTracker = null;
spokes.clear();
}
}