/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.configuration.internal;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.FrameworkUtil;
import de.rcenvironment.core.toolkitbridge.api.StaticToolkitHolder;
import de.rcenvironment.core.utils.common.service.AdditionalServiceDeclaration;
import de.rcenvironment.core.utils.common.service.AdditionalServicesProvider;
import de.rcenvironment.core.utils.common.service.AdditionalServicesRegistrationService;
import de.rcenvironment.core.utils.incubator.ServiceRegistry;
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;
/**
* {@link AdditionalServicesRegistrationService} implementation that uses the global {@link ServiceRegistry} to register the requested
* additional services.
*
* TODO review: use an internal {@link OsgiServiceRegistryAccessFactory} instead of the global {@link ServiceRegistry}?
*
* @author Robert Mischke
*/
public class OsgiAdditionalServicesRegistrationServiceImpl implements AdditionalServicesRegistrationService {
private final Map<AdditionalServicesProvider, ServiceRegistryPublisherAccess> sraMap = new HashMap<>();
private final OsgiServiceRegistryAccessFactory serviceRegistryAccessFactory;
private final Log log = LogFactory.getLog(getClass());
private final CounterCategory counterCategory;
public OsgiAdditionalServicesRegistrationServiceImpl() {
serviceRegistryAccessFactory = new OsgiServiceRegistryAccessFactory(FrameworkUtil.getBundle(this.getClass()).getBundleContext());
counterCategory =
StaticToolkitHolder.getService(StatisticsTrackerService.class).getCounterCategory(
"Additional Service registrations via AdditionalServicesProvider API", StatisticsFilterLevel.DEVELOPMENT);
}
@Override
public void registerAdditionalServicesProvider(AdditionalServicesProvider additionalServicesProvider) {
synchronized (sraMap) {
if (sraMap.get(additionalServicesProvider) != null) {
throw new IllegalStateException("Duplicate registration of ListenerProvider " + additionalServicesProvider);
}
ServiceRegistryPublisherAccess sra = serviceRegistryAccessFactory.createPublisherAccessFor(additionalServicesProvider);
sraMap.put(additionalServicesProvider, sra);
for (AdditionalServiceDeclaration declaration : additionalServicesProvider.defineAdditionalServices()) {
final Class<?> clazz = declaration.getServiceClass();
final Object implementation = declaration.getImplementation();
if (!clazz.isInstance(implementation)) {
throw new IllegalStateException("Invalid ListenerDeclaration: implementation does not implement declared interface "
+ clazz + ": " + implementation);
}
log.debug("Registering " + clazz.getSimpleName() + " listener on behalf of " + additionalServicesProvider);
sra.registerService(clazz, implementation);
counterCategory.count(clazz.getName());
}
}
}
@Override
public void unregisterAdditionalServicesProvider(AdditionalServicesProvider listenerProvider) {
synchronized (sraMap) {
final ServiceRegistryPublisherAccess sra = sraMap.get(listenerProvider);
if (sra == null) {
throw new IllegalStateException("No registration found for ListenerProvider " + listenerProvider);
}
sraMap.remove(listenerProvider);
log.debug("Disposing listeners of " + listenerProvider);
sra.dispose();
}
}
}