/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.configuration.internal; import java.util.ArrayList; import java.util.List; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import de.rcenvironment.core.toolkitbridge.api.StaticToolkitHolder; import de.rcenvironment.core.utils.incubator.ServiceRegistryAccess; import de.rcenvironment.core.utils.incubator.ServiceRegistryPublisherAccess; import de.rcenvironment.toolkit.modules.statistics.api.CounterCategory; import de.rcenvironment.toolkit.modules.statistics.api.StatisticsFilterLevel; import de.rcenvironment.toolkit.modules.statistics.api.StatisticsTrackerService; /** * A {@link ServiceRegistryAccess} implementation that registers and acquires services at the OSGi service registry. * * @author Robert Mischke */ public class OsgiServiceRegistryAccess implements ServiceRegistryPublisherAccess { private final BundleContext bundleContext; private final List<ServiceRegistration<?>> serviceRegistrations = new ArrayList<ServiceRegistration<?>>(); private final List<ServiceReference<?>> serviceReferences = new ArrayList<ServiceReference<?>>(); private final CounterCategory counterCategory; public OsgiServiceRegistryAccess(BundleContext bundleContext) { this.bundleContext = bundleContext; counterCategory = StaticToolkitHolder.getService(StatisticsTrackerService.class).getCounterCategory( "Additional Service registrations via OsgiServiceRegistryAccess API", StatisticsFilterLevel.DEVELOPMENT); } @Override @SuppressWarnings("unchecked") public <T> T getService(Class<T> clazz) { synchronized (serviceReferences) { ServiceReference<?> serviceReference = bundleContext.getServiceReference(clazz.getName()); if (serviceReference == null) { throw new IllegalStateException("Found no registered service for class " + clazz.getName()); } // FIXME review @7.0.0: this looks like a memory leak after the change to a "stateless" read access API; // distinguish between static/dynamic services regarding disposal and caching? - misc_ro serviceReferences.add(serviceReference); return (T) bundleContext.getService(serviceReference); } } /** * Registers an implementation for a service interface. * * @param <T> the interface class to register for * @param clazz the interface class to register for * @param implementation the implementation to register */ @Override public <T> void registerService(Class<T> clazz, Object implementation) { synchronized (serviceRegistrations) { serviceRegistrations.add(bundleContext.registerService(clazz.getName(), implementation, null)); } counterCategory.count(clazz.getName()); } @Override public void dispose() { synchronized (serviceReferences) { for (ServiceReference<?> serviceReference : serviceReferences) { bundleContext.ungetService(serviceReference); } serviceReferences.clear(); } synchronized (serviceRegistrations) { for (ServiceRegistration<?> registration : serviceRegistrations) { registration.unregister(); } serviceRegistrations.clear(); } } }