blob: 17342147ae4777d44abd8bd9550dbb2c43b748bd [file] [log] [blame]
/****************************************************************************
* Copyright (c) 2007 Versant Corp.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Markus Kuppe (mkuppe <at> versant <dot> com) - initial API and implementation
*
* SPDX-License-Identifier: EPL-2.0
*****************************************************************************/
package org.eclipse.ecf.internal.provider.jslp;
import ch.ethz.iks.slp.Advertiser;
import ch.ethz.iks.slp.Locator;
import java.util.Hashtable;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.ecf.core.*;
import org.eclipse.ecf.core.identity.Namespace;
import org.eclipse.ecf.core.util.ExtensionRegistryRunnable;
import org.eclipse.ecf.core.util.Trace;
import org.eclipse.ecf.discovery.IDiscoveryAdvertiser;
import org.eclipse.ecf.discovery.IDiscoveryLocator;
import org.eclipse.ecf.discovery.service.IDiscoveryService;
import org.eclipse.ecf.provider.jslp.container.ContainerInstantiator;
import org.eclipse.ecf.provider.jslp.container.JSLPDiscoveryContainer;
import org.eclipse.ecf.provider.jslp.identity.JSLPNamespace;
import org.osgi.framework.*;
import org.osgi.util.tracker.ServiceTracker;
public class Activator implements BundleActivator {
// The shared instance
private static Activator plugin;
public static final String PLUGIN_ID = "org.eclipse.ecf.provider.jslp"; //$NON-NLS-1$
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
// we need to keep a ref on our context
// @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=108214
private volatile BundleContext bundleContext;
private volatile ServiceTracker<Locator, Locator> locatorSt;
private volatile ServiceTracker<Advertiser, Advertiser> advertiserSt;
private volatile ServiceRegistration<?> serviceRegistration;
/**
* The constructor
*/
public Activator() {
plugin = this;
}
public Bundle getBundle() {
return bundleContext.getBundle();
}
public LocatorDecorator getLocator() {
locatorSt.open();
final Locator aLocator = locatorSt.getService();
if (aLocator == null) {
return new NullPatternLocator();
}
return new LocatorDecoratorImpl(aLocator);
}
public Advertiser getAdvertiser() {
advertiserSt.open();
final Advertiser advertiser = advertiserSt.getService();
if (advertiser == null) {
return new NullPatternAdvertiser();
}
return advertiser;
}
private static final boolean ENABLE_JSLP = Boolean.valueOf(System.getProperty("ch.ethz.iks.slp.enable", "false")); //$NON-NLS-1$ //$NON-NLS-2$
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
*/
public void start(final BundleContext context) throws Exception {
if (ENABLE_JSLP) {
bundleContext = context;
SafeRunner.run(new ExtensionRegistryRunnable(context) {
protected void runWithoutRegistry() throws Exception {
context.registerService(Namespace.class, new JSLPNamespace(), null);
context.registerService(ContainerTypeDescription.class, new ContainerTypeDescription("ecf.discovery.jslp", new ContainerInstantiator(), "JSLP Discovery Container", true, false), null); //$NON-NLS-1$//$NON-NLS-2$
context.registerService(ContainerTypeDescription.class, new ContainerTypeDescription("ecf.discovery.jslp.locator", new ContainerInstantiator(), "JSLP Discovery Locator Container", true, false), null); //$NON-NLS-1$//$NON-NLS-2$
context.registerService(ContainerTypeDescription.class, new ContainerTypeDescription("ecf.discovery.jslp.advertiser", new ContainerInstantiator(), "JSLP Discovery Advertiser Container", true, false), null); //$NON-NLS-1$//$NON-NLS-2$
}
});
// initially get the locator and add a life cycle listener
locatorSt = new ServiceTracker<Locator, Locator>(context, Locator.class.getName(), null);
// initially get the advertiser and add a life cycle listener
advertiserSt = new ServiceTracker<Advertiser, Advertiser>(context, Advertiser.class.getName(), null);
// register ourself as an OSGi service
final Hashtable<String, Object> props = new Hashtable<String, Object>();
props.put(IDiscoveryService.CONTAINER_NAME, JSLPDiscoveryContainer.NAME);
props.put(Constants.SERVICE_RANKING, Integer.valueOf(500));
String[] clazzes = new String[] {IDiscoveryService.class.getName(), IDiscoveryLocator.class.getName(), IDiscoveryAdvertiser.class.getName()};
serviceRegistration = context.registerService(clazzes, serviceFactory, props);
}
}
private final DiscoveryServiceFactory serviceFactory = new DiscoveryServiceFactory();
class DiscoveryServiceFactory implements ServiceFactory {
private volatile JSLPDiscoveryContainer jdc;
/* (non-Javadoc)
* @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
*/
public Object getService(final Bundle bundle, final ServiceRegistration registration) {
if (jdc == null) {
try {
jdc = new JSLPDiscoveryContainer();
jdc.connect(null, null);
} catch (final ContainerConnectException e) {
Trace.catching(Activator.PLUGIN_ID, Activator.PLUGIN_ID + "/debug/methods/tracing", this.getClass(), "getService(Bundle, ServiceRegistration)", e); //$NON-NLS-1$ //$NON-NLS-2$
jdc = null;
}
}
return jdc;
}
/**
* @return false if this factory has never created a service instance, true otherwise
*/
public boolean isActive() {
return jdc != null;
}
/* (non-Javadoc)
* @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration, java.lang.Object)
*/
public void ungetService(final Bundle bundle, final ServiceRegistration registration, final Object service) {
//TODO-mkuppe we later might want to dispose jSLP when the last!!! consumer ungets the service
//Though don't forget about the (ECF) Container which might still be in use
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(final BundleContext context) throws Exception {
//TODO-mkuppe here we should do something like a deregisterAll(), but see ungetService(...);
if (serviceRegistration != null && serviceFactory.isActive()) {
ServiceReference<?> reference = serviceRegistration.getReference();
IDiscoveryLocator aLocator = (IDiscoveryLocator) context.getService(reference);
serviceRegistration.unregister();
IContainer container = aLocator.getAdapter(IContainer.class);
container.disconnect();
container.dispose();
serviceRegistration = null;
}
plugin = null;
bundleContext = null;
if (advertiserSt != null) {
advertiserSt.close();
advertiserSt = null;
}
if (locatorSt != null) {
locatorSt.close();
locatorSt = null;
}
}
}