All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.dynamicextensionsalfresco.osgi.ServiceBundleContextRegistrar Maven / Gradle / Ivy

Go to download

Adds an OSGi container to alfresco repository supporting dynamic code reloading, classpath isolation and a bunch of other useful features

There is a newer version: 3.1.0
Show newest version
package com.github.dynamicextensionsalfresco.osgi;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.alfresco.service.descriptor.Descriptor;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.util.VersionNumber;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * Registers beans from an {@link ApplicationContext} as services in a {@link BundleContext}.
 * 
 * @author Laurens Fridael
 * 
 */
@Service
public class ServiceBundleContextRegistrar implements BundleContextRegistrar, ApplicationContextAware {

	/* Service property */
	private static final String ALFRESCO_SERVICE_TYPE = "alfresco.service.type";

	/* Service property for the Blueprint component name. */
	private static final String OSGI_SERVICE_BLUEPRINT_COMPNAME = "osgi.service.blueprint.compname";

	private final Logger logger = LoggerFactory.getLogger(getClass());

	/* Dependencies */

	private ApplicationContext applicationContext;

	private DescriptorService descriptorService;

	/* Configuration */

	private List serviceDefinitions = Collections.emptyList();

	private List servicePropertiesProviders = Collections.emptyList();

	private final List> serviceRegistrations = new ArrayList>();

	/* Operations */

	@Override
	public List> registerInBundleContext(final BundleContext bundleContext) {
		Assert.notNull(bundleContext, "BundleContext cannot be null.");

		final Descriptor descriptor = getDescriptorService().getServerDescriptor();
		if (descriptor == null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Could not obtain Descriptor. This is normal when running an integration test.");
			}
		}

		for (final ServiceDefinition serviceDefinition : getServiceDefinitions()) {
			int serviceRanking = 0;
			for (final String beanName : serviceDefinition.getBeanNames()) {
				final List serviceNames = serviceDefinition.getServiceNames();
				final String requiredPlatformVersion = serviceDefinition.getPlatformVersion();
				if (StringUtils.hasText(requiredPlatformVersion)) {
					final VersionNumber versionNumber = new VersionNumber(requiredPlatformVersion);
					if (descriptor != null && versionNumber.compareTo(descriptor.getVersionNumber()) > 0) {
						if (logger.isDebugEnabled()) {
							logger.debug(
									"Skipping registration of ServiceDefinitions {} because they require Alfresco version {}",
									serviceNames, requiredPlatformVersion);
						}
						continue;
					}
				}
				if (getApplicationContext().containsBean(beanName) == false) {
					if (logger.isWarnEnabled()) {
						logger.warn(
								"Could not find service \"{}\". This service will not be registered in the OSGI container.",
								beanName);
					}
					continue;
				}
				if (getApplicationContext().isSingleton(beanName) == false) {
					if (logger.isWarnEnabled()) {
						logger.warn(String.format(
								"Service \"%s\" is not a singleton. Can only register singleton beans.", beanName));
					}
					continue;
				}
				final Object service = getApplicationContext().getBean(beanName);
				if (service == null) {
					if (logger.isWarnEnabled()) {
						logger.warn("Cannot find bean '{}'", beanName);
					}
					continue;
				}
				try {
					final ServiceRegistration serviceRegistration = registerService(bundleContext, service,
							serviceNames, beanName, serviceDefinition.getServiceType(), serviceRanking);
					serviceRanking -= 1;
					serviceRegistrations.add(serviceRegistration);
				} catch (final RuntimeException e) {
					logger.error("Could not register bean \"{} \" as service", beanName);
				}
			}
		}
		if (logger.isInfoEnabled()) {
			logger.info("Registered {} OSGI services.", serviceRegistrations.size());
		}
		return Collections.unmodifiableList(serviceRegistrations);
	}

	protected ServiceRegistration registerService(final BundleContext bundleContext, final Object service,
			final List serviceNames, final String beanName, final String serviceType, final int serviceRanking) {
		Assert.notNull(service, "Service cannot be null.");
		Assert.notEmpty(serviceNames, "Service names cannot be empty.");

		final Hashtable serviceProperties = new Hashtable();
		serviceProperties.put(OSGI_SERVICE_BLUEPRINT_COMPNAME, beanName);
		serviceProperties.put("hostApplication", "alfresco");
		if (StringUtils.hasText(serviceType)) {
			serviceProperties.put(ALFRESCO_SERVICE_TYPE, serviceType);
		}
		serviceProperties.put(Constants.SERVICE_RANKING, serviceRanking);
		for (final ServicePropertiesProvider servicePropertiesProvider : getServicePropertiesProviders()) {
			final Map props = servicePropertiesProvider.getServiceProperties(service, serviceNames);
			if (CollectionUtils.isEmpty(props) == false) {
				serviceProperties.putAll(props);
			}
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Registering bean \"{}\" under service names {} with properties {}", beanName,
                serviceNames, serviceProperties);
		}
        return bundleContext.registerService(
                serviceNames.toArray(new String[serviceNames.size()]), service, serviceProperties);
	}

	public void unregisterFromBundleContext() {
		for (final ServiceRegistration serviceRegistration : serviceRegistrations) {
			try {
				if (logger.isDebugEnabled()) {
					logger.debug("Unregistering service: {}",
							serviceRegistration.getReference().getProperty(Constants.OBJECTCLASS));
				}
				serviceRegistration.unregister();
			} catch (final RuntimeException e) {
				logger.error("Error unregistering service.", e);
			}
		}
		serviceRegistrations.clear();
	}

	/* Dependencies */

	@Override
	public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	protected ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	public void setDescriptorService(final DescriptorService descriptorService) {
		this.descriptorService = descriptorService;
	}

	protected DescriptorService getDescriptorService() {
		return descriptorService;
	}

	/* Configuration */

	@Required
	public void setServiceDefinitions(final List serviceDefinitions) {
		Assert.notNull(serviceDefinitions);
		this.serviceDefinitions = serviceDefinitions;
	}

	protected List getServiceDefinitions() {
		return serviceDefinitions;
	}

	public void setServicePropertiesProviders(final List servicePropertiesProviders) {
		Assert.notNull(servicePropertiesProviders);
		this.servicePropertiesProviders = servicePropertiesProviders;
	}

	protected List getServicePropertiesProviders() {
		return servicePropertiesProviders;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy