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: [email protected]
For additional commands, e-mail: [email protected]