X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=cms%2Forg.argeo.slc.spring%2Fsrc%2Forg%2Fargeo%2Fslc%2Fosgi%2FMultipleServiceExporterPostProcessor.java;fp=cms%2Forg.argeo.slc.spring%2Fsrc%2Forg%2Fargeo%2Fslc%2Fosgi%2FMultipleServiceExporterPostProcessor.java;h=01509c273134fdfd3465535fdf34b49df2d96d48;hb=ecc22e604e47533c79de9cecdcdeacbc752cbff1;hp=0000000000000000000000000000000000000000;hpb=e07ded4632e53f8b8869763bc1f1f4091361e76e;p=gpl%2Fargeo-slc.git diff --git a/cms/org.argeo.slc.spring/src/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java b/cms/org.argeo.slc.spring/src/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java new file mode 100644 index 000000000..01509c273 --- /dev/null +++ b/cms/org.argeo.slc.spring/src/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java @@ -0,0 +1,146 @@ +package org.argeo.slc.osgi; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.core.Ordered; + +/** Publishes beans of the application context as OSGi services. */ +@SuppressWarnings(value = { "unchecked", "rawtypes" }) +public class MultipleServiceExporterPostProcessor implements + ApplicationListener, Ordered { + private final static Log log = LogFactory + .getLog(MultipleServiceExporterPostProcessor.class); + + private List interfaces = new ArrayList(); + + private int order = Ordered.LOWEST_PRECEDENCE; + + private BundleContext bundleContext = null; + + // private Class osgiServiceFactoryClass = OsgiServiceFactoryBean.class; + // private Boolean useServiceProviderContextClassLoader = false; + + public void onApplicationEvent(ApplicationEvent event) { + Map beans = new HashMap(); + if (event instanceof ContextRefreshedEvent) { + if (bundleContext != null) { + for (Class clss : interfaces) { + ApplicationContext ac = ((ContextRefreshedEvent) event) + .getApplicationContext(); + beans.putAll(ac.getBeansOfType(clss, false, false)); + } + + int count = 0; + for (String beanName : beans.keySet()) { + Object bean = beans.get(beanName); + List classes = new ArrayList(); + for (Class clss : interfaces) { + if (clss.isAssignableFrom(bean.getClass())) { + classes.add(clss.getName()); + } + } + Properties props = new Properties(); + Bundle bundle = bundleContext.getBundle(); + props.put(Constants.BUNDLE_SYMBOLICNAME, + bundle.getSymbolicName()); + props.put(Constants.BUNDLE_VERSION, bundle.getVersion()); + // retrocompatibility with pre-1.0: + props.put("org.eclipse.gemini.blueprint.bean.name", beanName); + bundleContext.registerService( + classes.toArray(new String[classes.size()]), bean, + new Hashtable(props)); + count++; + } + if (log.isTraceEnabled()) + log.trace("Published " + count + " " + interfaces + + " as OSGi services from bundle " + + bundleContext.getBundle().getSymbolicName() + " " + + bundleContext.getBundle().getVersion()); + // note: the services will be automatically unregistered when + // the bundle will be stopped + } + } + } + + // public void postProcessBeanFactory( + // ConfigurableListableBeanFactory beanFactory) throws BeansException { + // if (!(beanFactory instanceof BeanDefinitionRegistry)) { + // throw new SlcException("Can only work on " + // + BeanDefinitionRegistry.class); + // } + // + // long begin = System.currentTimeMillis(); + // + // // Merge all beans implementing these interfaces + // Set beanNames = new HashSet(); + // for (Class clss : interfaces) { + // String[] strs = beanFactory.getBeanNamesForType(clss, true, false); + // beanNames.addAll(Arrays.asList(strs)); + // } + // + // // Register service factory beans for them + // for (String beanName : beanNames) { + // MutablePropertyValues mpv = new MutablePropertyValues(); + // mpv.addPropertyValue("interfaces", interfaces.toArray()); + // mpv.addPropertyValue("targetBeanName", beanName); + // if (useServiceProviderContextClassLoader) + // mpv.addPropertyValue("contextClassLoader", + // ExportContextClassLoader.SERVICE_PROVIDER); + // RootBeanDefinition bd = new RootBeanDefinition( + // osgiServiceFactoryClass, mpv); + // + // String exporterBeanName = "osgiService." + beanName; + // if (log.isTraceEnabled()) + // log.debug("Registering OSGi service exporter " + // + exporterBeanName); + // ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition( + // exporterBeanName, bd); + // } + // + // long end = System.currentTimeMillis(); + // if (log.isTraceEnabled()) + // log.debug("Multiple services exported in " + (end - begin) + // + " ms in bundle."); + // + // } + + public void setInterfaces(List interfaces) { + this.interfaces = interfaces; + } + + // public void setOsgiServiceFactoryClass(Class osgiServiceFactoryClass) { + // this.osgiServiceFactoryClass = osgiServiceFactoryClass; + // } + + public int getOrder() { + return order; + } + + public void setOrder(int order) { + this.order = order; + } + + // public void setUseServiceProviderContextClassLoader( + // Boolean useServiceProviderContextClassLoader) { + // this.useServiceProviderContextClassLoader = + // useServiceProviderContextClassLoader; + // } + + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } +}