package ddth.dasp.framework.osgi;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext;
/**
* This {@link BundleActivator} does the following:
* <ul>
* <li>On bundle start:
* <ul>
* <li>Saves instance of bundle context and bundle for latter use. See
* {@link #setBundleContext(BundleContext)} and {@link #setBundle(Bundle)}.</li>
* <li>Builds bundle's properties. See {@link #setProperties(Properties)}.</li>
* <li>Calls {@link #registerSpringMvcHandlerMapping()} and
* {@link #registerSpringMvcViewResolver()}.</li>
* <li>Calls {@link #registerServices()}.</li>
* </ul>
* </li>
* <li>On bundle stop:
* <ul>
* <li>Calls {@link #unregisterServices()}.</li>
* </ul>
* </li>
* </ul>
*
* @author NBThanh <btnguyen2k@gmail.com>
*/
public abstract class BaseSpringBundleActivator extends BaseBundleActivator {
private final Logger LOGGER = LoggerFactory.getLogger(BaseSpringBundleActivator.class);
private OsgiBundleXmlApplicationContext applicationContext;
/**
* Gets Spring's {@link ApplicationContext} instance.
*
* @return
*/
protected ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* Gets a Spring bean by name.
*
* @param name
* @return
*/
protected Object getSpringBean(String name) {
if (applicationContext == null) {
return null;
}
try {
Object bean = applicationContext.getBean(name);
return bean;
} catch (Exception e) {
LOGGER.warn(e.getMessage(), e);
return null;
}
}
/**
* Gets a Spring bean by class.
*
* @param <T>
* @param clazz
* @return
*/
protected <T> T getSpringBean(Class<T> clazz) {
if (applicationContext == null) {
return null;
}
try {
T bean = applicationContext.getBean(clazz);
return bean;
} catch (Exception e) {
LOGGER.warn(e.getMessage(), e);
return null;
}
}
/**
* Gets a Spring bean by name and class .
*
* @param <T>
* @param name
* @param clazz
* @return
*/
protected <T> T getSpringBean(String name, Class<T> clazz) {
if (applicationContext == null) {
return null;
}
try {
T bean = applicationContext.getBean(name, clazz);
return bean;
} catch (Exception e) {
LOGGER.warn(e.getMessage(), e);
return null;
}
}
/**
* Gets list of Spring's configuration files.
*
* Sub-class return <code>null</code> or an empty array to indicate that it
* does not need Spring's {@link ApplicationContext}.
*
* @return
*/
protected abstract String[] getSpringConfigFiles();
protected void initApplicationContext() throws Exception {
OsgiBundleXmlApplicationContext ac = new OsgiBundleXmlApplicationContext();
try {
ac.setBundleContext(getBundleContext());
ac.setPublishContextAsService(false);
String[] springConfigFiles = getSpringConfigFiles();
if (springConfigFiles != null && springConfigFiles.length > 0) {
ac.setConfigLocations(springConfigFiles);
}
// ac.refresh();
ac.normalRefresh();
ac.start();
} catch (Exception e) {
ac.close();
throw e;
}
this.applicationContext = ac;
}
protected void destroyApplicationContext() throws Exception {
if (applicationContext != null) {
applicationContext.close();
}
}
/**
* {@inheritDoc}
*/
@Override
protected List<ServiceInfo> getServiceInfoList() {
List<ServiceInfo> result = super.getServiceInfoList();
if (result == null) {
result = new ArrayList<ServiceInfo>();
}
Map<String, IServiceAutoRegister> autoBeans = applicationContext
.getBeansOfType(IServiceAutoRegister.class);
for (Map.Entry<String, IServiceAutoRegister> entry : autoBeans.entrySet()) {
IServiceAutoRegister service = entry.getValue();
ServiceInfo serviceInfo = new ServiceInfo(service.getClassName(), service,
service.getProperties());
result.add(serviceInfo);
}
return result;
}
/**
* {@inheritDoc}
*/
@Override
protected void internalBundleStart(BundleContext bundleContext) throws Exception {
setBundleContext(bundleContext);
setBundle(bundleContext.getBundle());
initApplicationContext();
super.internalBundleStart(bundleContext);
}
/**
* {@inheritDoc}
*/
@Override
protected void internalBundleStop(BundleContext bundleContext) throws Exception {
try {
destroyApplicationContext();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
try {
super.internalBundleStop(bundleContext);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
}