Skip to content

Commit

Permalink
Made it easier to export serivice.s
Browse files Browse the repository at this point in the history
  • Loading branch information
ieb committed Apr 3, 2009
1 parent e7eef2c commit 008fc06
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@
package org.sakaiproject.kernel.persistence;


import com.google.inject.Module;

import org.osgi.framework.BundleContext;
import org.sakaiproject.kernel.guice.AbstractOsgiModule;
import org.sakaiproject.kernel.guice.GuiceActivator;

/**
Expand All @@ -33,7 +32,7 @@ public class Activator extends GuiceActivator {
* @see org.sakaiproject.kernel.guice.GuiceActivator#getModule()
*/
@Override
protected Module getModule(BundleContext bundleContext) {
protected AbstractOsgiModule getModule(BundleContext bundleContext) {
return new ActivatorModule(bundleContext);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,10 @@
import org.sakaiproject.kernel.api.memory.CacheManagerService;
import org.sakaiproject.kernel.api.persistence.DataSourceService;
import org.sakaiproject.kernel.guice.AbstractOsgiModule;
import org.sakaiproject.kernel.guice.OsgiServiceProvider;
import org.sakaiproject.kernel.guice.ServiceExportList;
import org.sakaiproject.kernel.persistence.dbcp.DataSourceServiceImpl;
import org.sakaiproject.kernel.persistence.eclipselink.EntityManagerFactoryProvider;
import org.sakaiproject.kernel.persistence.geronimo.TransactionManagerProvider;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
Expand Down Expand Up @@ -64,24 +60,24 @@ protected void configure() {
bind(EntityManagerFactory.class).toProvider(
EntityManagerFactoryProvider.class).in(Scopes.SINGLETON);
// bind the EntityManager to a ScopedEntityManger
bind(EntityManager.class).to(ScopedEntityManager.class)
bind(export(EntityManager.class)).to(ScopedEntityManager.class)
.in(Scopes.SINGLETON);
// Bind in the datasource
bind(DataSource.class).toProvider(DataSourceServiceImpl.class).in(
bind(export(DataSource.class)).toProvider(DataSourceServiceImpl.class).in(
Scopes.SINGLETON);
// and the transaction manager via a provider.
bind(TransactionManager.class).toProvider(TransactionManagerProvider.class)
bind(export(TransactionManager.class)).toProvider(TransactionManagerProvider.class)
.in(Scopes.SINGLETON);

// bind the services
bind(DataSourceService.class).to(DataSourceServiceImpl.class).in(
Scopes.SINGLETON);

bind(CacheManagerService.class).toProvider(new OsgiServiceProvider<CacheManagerService>(CacheManagerService.class,bundleContext));
bind(CacheManagerService.class).toProvider(importService(CacheManagerService.class).asSingleton());

bind(List.class).annotatedWith(ServiceExportList.class).toProvider(ServiceExportProvider.class);
}


/**
* {@inheritDoc}
* @see org.sakaiproject.kernel.guice.AbstractOsgiModule#getBundleContext()
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package org.sakaiproject.kernel.guice;

import com.google.common.collect.Sets;
import com.google.inject.AbstractModule;
import com.google.inject.name.Names;

Expand All @@ -26,13 +27,15 @@
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Set;

/**
* Provides configuration support.
*/
public abstract class AbstractOsgiModule extends AbstractModule {

private static final Logger LOGGER = LoggerFactory.getLogger(AbstractOsgiModule.class);
private Set<Class<?>> exports = Sets.newHashSet();

/**
* {@inheritDoc}
Expand All @@ -55,4 +58,31 @@ protected void configure() {
*/
protected abstract BundleContext getBundleContext();


/**
* @param class1
* @return
*/
protected <T> Class<T> export(Class<T> clazz) {
exports.add(clazz);
return clazz;
}

/**
* @param class1
* @return
*/
protected <T> OsgiServiceProvider<T> importService(Class<T> class1) {
return new OsgiServiceProvider<T>(class1,getBundleContext());
}



/**
* @return the exports
*/
public Set<Class<?>> getExports() {
return exports;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,13 @@
import com.google.common.collect.Sets;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;

import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;

/**
Expand All @@ -41,20 +38,22 @@
public abstract class GuiceActivator implements BundleActivator {

private Injector injector;
private List<?> services;
private Set<Class<?>> services;

/**
* {@inheritDoc}
*
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext bundleContext) throws Exception {
injector = Guice.createInjector(getModule(bundleContext));
AbstractOsgiModule module = getModule(bundleContext);
injector = Guice.createInjector(module);

services = injector.getInstance(Key.get(List.class, ServiceExportList.class));
for (Object o : services) {
if (o.getClass().isAnnotationPresent(ServiceExportDescription.class)) {
ServiceExportDescription ks = o.getClass().getAnnotation(
services = module.getExports();
for (Class<?> serviceClass : services) {
Object service = injector.getInstance(serviceClass);
if (serviceClass.isAnnotationPresent(ServiceExportDescription.class)) {
ServiceExportDescription ks = serviceClass.getAnnotation(
ServiceExportDescription.class);
Dictionary<String, Object> dictionary = new Hashtable<String, Object>();
Class<?>[] serviceClasses = ks.serviceClasses();
Expand All @@ -66,13 +65,13 @@ public void start(BundleContext bundleContext) throws Exception {
dictionary.put(Constants.OBJECTCLASS, serviceClassNames);
dictionary.put(Constants.SERVICE_DESCRIPTION, ks.serviceDescription());
dictionary.put(Constants.SERVICE_VENDOR, ks.seviceVendor());
bundleContext.registerService(serviceClassNames, o, dictionary);
bundleContext.registerService(serviceClassNames, service, dictionary);
} else {
Class<?>[] implementedInterfaces = o.getClass().getInterfaces();
o.getClass().isInterface();
Class<?>[] implementedInterfaces = serviceClass.getInterfaces();
serviceClass.isInterface();
Set<Class<?>> interfaces = Sets.newHashSet();
if (o.getClass().isInterface()) {
interfaces.add(o.getClass());
if (serviceClass.isInterface()) {
interfaces.add(serviceClass);
}
for (Class<?> c : implementedInterfaces) {
interfaces.add(c);
Expand All @@ -84,9 +83,9 @@ public void start(BundleContext bundleContext) throws Exception {
serviceClassNames[i++] = c.getName();
}
dictionary.put(Constants.OBJECTCLASS, serviceClassNames);
dictionary.put(Constants.SERVICE_DESCRIPTION, o.getClass().getName());
dictionary.put(Constants.SERVICE_DESCRIPTION, serviceClass.getName());
dictionary.put(Constants.SERVICE_VENDOR, "The Sakai Foundation");
bundleContext.registerService(serviceClassNames, o, dictionary);
bundleContext.registerService(serviceClassNames, service, dictionary);
}
}
}
Expand All @@ -107,6 +106,6 @@ public void stop(BundleContext bundleContext) throws Exception {
/**
* @return
*/
protected abstract Module getModule(BundleContext bundleContext);
protected abstract AbstractOsgiModule getModule(BundleContext bundleContext);

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,55 @@
/**
* Create a generic Guice provider that binds to a service in OSGi
*/
public class OsgiServiceProvider<T> implements
Provider<T> {
public class OsgiServiceProvider<T> implements Provider<T> {

private BundleContext bundleContext;
private ServiceReference serviceReference;
private boolean singleton = false;
private T service;
private Object serviceLock = new Object();;

/**
* @param the interface representing the service
* @param bundleContext the bundle context of this bundle
* @param the
* interface representing the service
* @param bundleContext
* the bundle context of this bundle
*/
public OsgiServiceProvider(Class<T> serviceClass,
BundleContext bundleContext) {
public OsgiServiceProvider(Class<T> serviceClass, BundleContext bundleContext) {
this.bundleContext = bundleContext;
// convert the service class into a reference, since the provision of the service class
// convert the service class into a reference, since the provision of the service
// class
// may change.
this.serviceReference = bundleContext.getServiceReference(serviceClass.getName());
}

/**
* {@inheritDoc}
*
* @see com.google.inject.Provider#get()
*/
@SuppressWarnings("unchecked")
public T get() {
return (T) bundleContext.getService(serviceReference);
if (singleton) {
if (service == null) {
synchronized (serviceLock) {
if (service == null) {
service = (T) bundleContext.getService(serviceReference);
}
}
}
return service;
} else {
return (T) bundleContext.getService(serviceReference);
}
}

/**
* @return
*/
public OsgiServiceProvider<T> asSingleton() {
singleton = true;
return this;
}

}

0 comments on commit 008fc06

Please sign in to comment.