/******************************************************************************* * Copyright (c) 2008, 2014 Stuart McCulloch * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Stuart McCulloch - initial API and implementation *******************************************************************************/ package org.eclipse.sisu.peaberry.osgi; import static org.osgi.framework.ServiceEvent.MODIFIED; import static org.osgi.framework.ServiceEvent.REGISTERED; import static org.osgi.framework.ServiceEvent.UNREGISTERING; import org.eclipse.sisu.peaberry.ServiceException; import org.eclipse.sisu.peaberry.cache.AbstractServiceListener; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; /** * Keep track of imported OSGi services that provide a specific interface. * * @author mcculls@gmail.com (Stuart McCulloch) */ final class OSGiServiceListener<T> extends AbstractServiceListener<T> implements ServiceListener { private final BundleContext bundleContext; private final String ldapFilter; OSGiServiceListener(final BundleContext bundleContext, final String ldapFilter) { this.bundleContext = bundleContext; this.ldapFilter = ldapFilter; } @Override protected synchronized void start() { try { // register listener first to avoid race condition bundleContext.addServiceListener(this, ldapFilter); // retrieve snapshot of any matching services that are already registered final ServiceReference[] refs = bundleContext.getServiceReferences(null, ldapFilter); if (null != refs) { // wrap service references to optimize sorting for (final ServiceReference r : refs) { insertService(new OSGiServiceImport<T>(bundleContext, r)); // NOPMD } } } catch (final InvalidSyntaxException e) { throw new ServiceException(e); // this should never happen! } } public synchronized void serviceChanged(final ServiceEvent event) { final OSGiServiceImport<T> service = new OSGiServiceImport<T>(bundleContext, event.getServiceReference()); switch (event.getType()) { case REGISTERED: insertService(service); break; case MODIFIED: updateService(service); break; case UNREGISTERING: removeService(service); break; default: break; } } }