/*- * Copyright © 2012 Diamond Light Source Ltd. * * This file is part of GDA. * * GDA is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License version 3 as published by the Free * Software Foundation. * * GDA is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with GDA. If not, see <http://www.gnu.org/licenses/>. */ package uk.ac.gda.common.rcp; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTrackerCustomizer; /* * A class that can be used by an Activator to provide support for services. Particularly useful * when selecting a service from a collection of services based on the String value of a property. * * namedServiceProvider = new NamedServiceProvider(bundleContext); * namedServiceProvider.getNamedService(clzz, "SERVICE_NAME", name); * * in bundle stop call namedServiceProvider.close() */ public class NamedServiceProvider { private BundleContext bundleContext; public NamedServiceProvider(BundleContext bundleContext) { this.bundleContext = bundleContext; if (bundleContext == null) throw new IllegalStateException("BundleContext is null"); } public void close() { if( !serviceTrackers.isEmpty()){ for (Entry<String, ServiceTracker<?, ?>> st : serviceTrackers.entrySet()) { st.getValue().close(); } serviceTrackers.clear(); } bundleContext = null; } Map<String, ServiceTracker<?, ?>> serviceTrackers = new HashMap<String, ServiceTracker<?, ?>>(); public <T> T getNamedService(Class<T> clzz, final String propertyKey, final String name) { if (bundleContext == null) throw new IllegalStateException("BundleContext is null"); boolean checkName = name !=null && !name.isEmpty(); String serviceClassAndName = clzz.getName(); if(checkName){ serviceClassAndName += (":" + propertyKey + ":" + name); } @SuppressWarnings("unchecked") ServiceTracker<T, T> tracker = (ServiceTracker<T, T>) serviceTrackers.get(serviceClassAndName); if (tracker == null) { ServiceTrackerCustomizer<T, T> customizer = null; if( checkName){ customizer = new ServiceTrackerCustomizer<T, T>() { @Override public T addingService(ServiceReference<T> reference) { if (reference.getProperty(propertyKey).equals(name)) return bundleContext.getService(reference); return null; } @Override public void modifiedService(ServiceReference<T> reference, T service) { } @Override public void removedService(ServiceReference<T> reference, T service) { } }; } tracker = new ServiceTracker<T, T>(bundleContext, clzz.getName(), customizer); tracker.open(true); serviceTrackers.put(serviceClassAndName, tracker); } return tracker.isEmpty() ? null : tracker.getService(); } }