package com.aol.micro.server.spring;
import java.util.List;
import cyclops.Streams;
import cyclops.stream.ReactiveSeq;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import com.aol.micro.server.Plugin;
import com.aol.micro.server.PluginLoader;
import com.aol.micro.server.config.Config;
import com.aol.micro.server.config.ConfigAccessor;
public class SpringApplicationConfigurator implements SpringBuilder {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public ConfigurableApplicationContext createSpringApp(Config config, Class... classes) {
logger.debug("Configuring Spring");
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.setAllowCircularReferences(config.isAllowCircularReferences());
rootContext.register(classes);
rootContext.scan(config.getBasePackages());
rootContext.refresh();
logger.debug("Configuring Additional Spring Beans");
ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) rootContext).getBeanFactory();
config.getDataSources()
.keySet()
.stream()
.filter(it -> !new ConfigAccessor().get()
.getDefaultDataSourceName()
.equals(it))
.forEach(name -> {
List<SpringDBConfig> dbConfig = getConfig(config, rootContext, beanFactory);
dbConfig.forEach(spring -> spring.createSpringApp(name));
});
logger.debug("Finished Configuring Spring");
return rootContext;
}
private List<SpringDBConfig> getConfig(Config config, AnnotationConfigWebApplicationContext rootContext,
ConfigurableListableBeanFactory beanFactory) {
List<SpringDBConfig> result = ReactiveSeq.fromStream(PluginLoader.INSTANCE.plugins.get()
.stream())
.filter(module -> module.springDbConfigurer() != null)
.map(Plugin::springDbConfigurer)
.flatMap(Streams::optionalToStream)
.toList();
result.forEach(next -> {
next.setBeanFactory(beanFactory);
next.setRootContext(rootContext);
next.setConfig(config);
});
return result;
}
}