james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nor...@apache.org
Subject svn commit: r1143674 - /james/server/trunk/container-spring/src/main/java/org/apache/james/container/spring/osgi/AbstractServiceTracker.java
Date Thu, 07 Jul 2011 06:39:32 GMT
Author: norman
Date: Thu Jul  7 06:39:31 2011
New Revision: 1143674

URL: http://svn.apache.org/viewvc?rev=1143674&view=rev
Log:
Make sure we register services in the BeanDefinationRegistry and in the OSGI-Registry. So
spring can do its job and wire everything together. See JAMES-835

Modified:
    james/server/trunk/container-spring/src/main/java/org/apache/james/container/spring/osgi/AbstractServiceTracker.java

Modified: james/server/trunk/container-spring/src/main/java/org/apache/james/container/spring/osgi/AbstractServiceTracker.java
URL: http://svn.apache.org/viewvc/james/server/trunk/container-spring/src/main/java/org/apache/james/container/spring/osgi/AbstractServiceTracker.java?rev=1143674&r1=1143673&r2=1143674&view=diff
==============================================================================
--- james/server/trunk/container-spring/src/main/java/org/apache/james/container/spring/osgi/AbstractServiceTracker.java
(original)
+++ james/server/trunk/container-spring/src/main/java/org/apache/james/container/spring/osgi/AbstractServiceTracker.java
Thu Jul  7 06:39:31 2011
@@ -19,10 +19,7 @@
 package org.apache.james.container.spring.osgi;
 
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
 
 import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.james.container.spring.lifecycle.ConfigurationProvider;
@@ -30,38 +27,37 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleListener;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.BeanFactory;
 import org.springframework.beans.factory.BeanFactoryAware;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
 import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
 import org.springframework.context.ApplicationContext;
 import org.springframework.osgi.context.BundleContextAware;
+import org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext;
 import org.springframework.osgi.service.exporter.OsgiServicePropertiesResolver;
-import org.springframework.osgi.service.exporter.support.BeanNameServicePropertiesResolver;
+import org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean;
 
 /**
  * This {@link BundleListener} use the extender pattern to scan all loaded
  * bundles if a class name with a given name is present. If so it register in
- * the {@link BeanDefinitionRegistry} and also register it to
- * {@link BundleContext} as service. This allows to dynamic load and unload OSGI
- * bundles
+ * the {@link BeanDefinitionRegistry} and also register it to the OSG-Registry via an {@link
OsgiServiceFactoryBean}
  * 
  */
 public abstract class AbstractServiceTracker implements BeanFactoryAware, BundleListener,
BundleContextAware, InitializingBean, DisposableBean {
 
     private BundleContext context;
     private String configuredClass;
-    private final List<ServiceRegistration> reg = new ArrayList<ServiceRegistration>();
+    private volatile OsgiServiceFactoryBean osgiFactoryBean;
     private BeanFactory factory;
-
+    private Logger logger = LoggerFactory.getLogger(AbstractServiceTracker.class);
+    
     @Override
     public void setBeanFactory(BeanFactory factory) throws BeansException {
         this.factory = factory;
@@ -72,7 +68,6 @@ public abstract class AbstractServiceTra
         this.context = context;
     }
 
-    @SuppressWarnings("unchecked")
     @Override
     public void bundleChanged(BundleEvent event) {
         Bundle b = event.getBundle();
@@ -87,49 +82,45 @@ public abstract class AbstractServiceTra
             Enumeration<?> entrs = b.findEntries("/", "*.class", true);
             if (entrs != null) {
 
-                // Loop over all the classes 
+                // Loop over all the classes
                 while (entrs.hasMoreElements()) {
                     URL e = (URL) entrs.nextElement();
                     String file = e.getFile();
 
                     String className = file.replaceAll("/", ".").replaceAll(".class", "").replaceFirst(".",
"");
                     if (className.equals(configuredClass)) {
-                        BeanFactory bFactory = getBeanFactory(b.getBundleContext());
-                        // Get the right service properties from the resolver
-                        Properties p = new Properties();
-
-                        // Setup a resolver
-                        BeanNameServicePropertiesResolver resolver = new BeanNameServicePropertiesResolver();
-                        resolver.setBundleContext(b.getBundleContext());
-
-                        
-                        p.putAll(resolver.getServiceProperties(getComponentName()));
-                        Class<?> clazz = getServiceClass();
-                        
-                        // Create the definition and register it
-                        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) bFactory;
-                        BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(className).getBeanDefinition();
-                        registry.registerBeanDefinition(getComponentName(), def);
+                        try {
+
+                            BeanFactory bFactory = getBeanFactory(b.getBundleContext());
+                            Class<?> clazz = getServiceClass();
 
-                        // register the bean as service in the BundleContext
-                        reg.add(b.getBundleContext().registerService(clazz.getName(), bFactory.getBean(getComponentName(),
clazz), p));
+                            // Create the definition and register it
+                            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) bFactory;
+                            BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(className).getBeanDefinition();
+                            registry.registerBeanDefinition(getComponentName(), def);
+
+                            // register the bean as service in the OSGI-Registry
+                            osgiFactoryBean = new OsgiServiceFactoryBean();
+                            osgiFactoryBean.setTargetBeanName(getComponentName());
+                            osgiFactoryBean.setBeanFactory(bFactory);
+                            osgiFactoryBean.setBundleContext(b.getBundleContext());
+                            osgiFactoryBean.setInterfaces(new Class[] { clazz });
+                            osgiFactoryBean.afterPropertiesSet();
+                            logger.debug("Registered " + configuredClass + " in the OSGI-Registry
with interface " + clazz.getName());
+                        } catch (Exception e1) {
+                            logger.error("Unable to register " + configuredClass + " in the
OSGI-Registry", e1);
+                        }
                     }
                 }
             }
             break;
         case BundleEvent.STOPPED:
-            if (reg != null) {
-                List<ServiceRegistration> removed = new ArrayList<ServiceRegistration>();
-                for (int i = 0; i < reg.size(); i++) {
-                    ServiceRegistration sr = reg.get(i);
-                    // Check if we need to unregister the service
-                    if (b.equals(sr.getReference().getBundle())) {
-                        sr.unregister();
-                        removed.add(sr);
-                    } 
-                }
-                reg.removeAll(removed);
-               
+            // check if we need to destroy the OsgiFactoryBean. This also include the unregister
from the OSGI-Registry
+            if (osgiFactoryBean != null) {
+                osgiFactoryBean.destroy();
+                osgiFactoryBean = null;
+                logger.debug("Unregistered " + configuredClass + " in the OSGI-Registry with
interface " + getServiceClass().getName());
+
             }
             break;
         default:
@@ -138,20 +129,33 @@ public abstract class AbstractServiceTra
 
     }
 
-    private static AutowireCapableBeanFactory getBeanFactory(final BundleContext bundleContext)
{
+    
+    /**
+     * Return the {@link BeanFactory} for the given {@link BundleContext}. If none can be
found we just create a new {@link AbstractDelegatedExecutionApplicationContext} and return
the {@link BeanFactory} of it
+     * 
+     * 
+     * @param bundleContext
+     * @return factory
+     * @throws Exception
+     */
+    private BeanFactory getBeanFactory(final BundleContext bundleContext) throws Exception
{
         final String filter = "(" + OsgiServicePropertiesResolver.BEAN_NAME_PROPERTY_KEY
+ "=" + bundleContext.getBundle().getSymbolicName() + ")";
-        final ServiceReference[] applicationContextRefs;       
-        try {
-            applicationContextRefs = bundleContext.getServiceReferences(ApplicationContext.class.getName(),
filter);
-        } catch (final InvalidSyntaxException e) {
-            throw new RuntimeException(e);
-        }
-       
-        if(applicationContextRefs.length != 1) {
-            return null;
+        final ServiceReference[] applicationContextRefs = bundleContext.getServiceReferences(ApplicationContext.class.getName(),
filter);
+        
+        // Check if we found an ApplicationContext. If not create one
+        if(applicationContextRefs == null || applicationContextRefs.length != 1) {
+            
+            // Create a new context which just serve as registry later
+            AbstractDelegatedExecutionApplicationContext context = new AbstractDelegatedExecutionApplicationContext()
{
+            };
+            context.setBundleContext(bundleContext);
+            context.setPublishContextAsService(true);
+            context.refresh();
+            return context.getBeanFactory();
+        } else {
+            return ((ApplicationContext) bundleContext.getService(applicationContextRefs[0])).getAutowireCapableBeanFactory();
         }
        
-        return ((ApplicationContext) bundleContext.getService(applicationContextRefs[0])).getAutowireCapableBeanFactory();
        
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Mime
View raw message