package org.foo.dosgi;
import java.util.HashMap;
import java.util.Map;
import org.foo.dosgi.helper.LogUtil;
import org.foo.dosgi.helper.PropertyUtil;
import org.foo.dosgi.helper.RegistryWatcher;
import org.foo.dosgi.hooks.ExportedServiceTracker;
import org.foo.dosgi.hooks.ImportedServiceFindHook;
import org.foo.dosgi.hooks.ImportedServiceListenerHook;
import org.foo.dosgi.registry.Registry;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.hooks.service.FindHook;
import org.osgi.framework.hooks.service.ListenerHook;
import org.osgi.util.tracker.ServiceTracker;
public class Activator implements BundleActivator {
class RegistryTracker extends ServiceTracker {
public RegistryTracker(BundleContext ctx) {
super(ctx, Registry.class.getName(), null);
}
@Override
public Object addingService(ServiceReference reference) {
Registry registry = (Registry) super.addingService(reference);
String[] intents = PropertyUtil.toStringArray(reference
.getProperty("remote.intents.supported"));
String[] configs = PropertyUtil.toStringArray(reference
.getProperty("remote.configs.supported"));
bindRegistry(registry, intents, configs);
return registry;
}
@Override
public void removedService(ServiceReference reference, Object service) {
unbindRegistry((Registry) service);
super.removedService(reference, service);
}
}
private volatile BundleContext ctx;
private volatile RegistryTracker tracker;
private Map<Registry, ServiceRegistration[]> serviceRegs = new HashMap<Registry, ServiceRegistration[]>();
private Map<Registry, RegistryWatcher> watchers = new HashMap<Registry, RegistryWatcher>();
private Map<Registry, ServiceTracker> trackers = new HashMap<Registry, ServiceTracker>();
public void start(BundleContext ctx) throws Exception {
this.ctx = ctx;
LogUtil.ctx = ctx;
tracker = new RegistryTracker(ctx);
tracker.open();
}
public void stop(BundleContext ctx) throws Exception {
tracker.close();
this.ctx = null;
}
private synchronized void bindRegistry(Registry registry,
String[] intents, String[] configs) {
RegistryWatcher watcher = new RegistryWatcher(ctx, registry);
watchers.put(registry, watcher);
ServiceRegistration[] regs = new ServiceRegistration[2];
ExportedServiceTracker export = new ExportedServiceTracker(ctx,
registry, intents, configs);
export.open();
trackers.put(registry, export);
ImportedServiceFindHook find = new ImportedServiceFindHook(watcher);
regs[0] = ctx.registerService(FindHook.class.getName(), find, null);
ImportedServiceListenerHook listener = new ImportedServiceListenerHook(
watcher);
regs[1] = ctx.registerService(ListenerHook.class.getName(), listener,
null);
serviceRegs.put(registry, regs);
}
private synchronized void unbindRegistry(Registry service) {
ServiceTracker tracker = trackers.remove(service);
if (tracker != null) {
tracker.close();
}
RegistryWatcher watcher = watchers.remove(service);
if (watcher != null) {
watcher.destroy();
}
ServiceRegistration[] regs = serviceRegs.remove(service);
if (regs != null) {
for (ServiceRegistration reg : regs) {
reg.unregister();
}
}
}
}