package cn.lechange.happor.context; import org.apache.log4j.Logger; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import cn.lechange.happor.ControllerRegistry; import cn.lechange.happor.ControllerScanner; import cn.lechange.happor.HapporContext; import cn.lechange.happor.HapporWebserver; import cn.lechange.happor.WebserverHandler; import cn.lechange.happor.controller.HttpController; import cn.lechange.happor.springtags.HapporServerElement; public class HapporSpringContext extends HapporContext { private static Logger logger = Logger.getLogger(HapporSpringContext.class); private FileSystemXmlApplicationContext ctx; private ClassLoader classLoader; public HapporSpringContext(String filename) { this(Thread.currentThread().getContextClassLoader(), filename); } public HapporSpringContext(final ClassLoader classLoader, String filename) { this.classLoader = classLoader; ctx = new FileSystemXmlApplicationContext(filename) { @Override protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) { super.initBeanDefinitionReader(reader); reader.setBeanClassLoader(classLoader); setClassLoader(classLoader); } }; registerAllBeans(); setServer(ctx.getBean(HapporWebserver.class)); try { setWebserverHandler(ctx.getBean(WebserverHandler.class)); } catch (NoSuchBeanDefinitionException e) { logger.warn("has no WebserverHandler"); } } public ApplicationContext getApplicationContext() { return ctx; } public void close() { if (ctx != null) { ctx.close(); } } @Override public HttpController getController(Class<? extends HttpController> clazz) { // TODO Auto-generated method stub return (HttpController) ctx.getBean(clazz); } @SuppressWarnings("unchecked") private void registerAllBeans() { HapporServerElement element = ctx.getBean(HapporServerElement.class); if (element != null) { registerWebserver(element.getServer()); if (element.getHandlerClass() != null) { try { Class<WebserverHandler> handlerClass = (Class<WebserverHandler>) classLoader .loadClass(element.getHandlerClass()); registerHandler(handlerClass); } catch (ClassNotFoundException e) { logger.error(e.getMessage()); } } if (element.getFilters() == null) { for (ControllerRegistry registry : element.getControllers()) { addControllerFromRegistry(registry); } } else { ControllerScanner scanner = new ControllerScanner(); scanner.scan(classLoader, element.getAutoScanPackage()); for (String name : element.getFilters()) { ControllerRegistry registry = scanner.getFilter(name); if (registry == null) { logger.error("no filter named '" + name + "'"); } else { addControllerFromRegistry(registry); } } for (ControllerRegistry registry : scanner.getHandlers()) { addControllerFromRegistry(registry); } } } } private void addControllerFromRegistry(ControllerRegistry registry) { String className = registry.getClassName(); try { @SuppressWarnings("unchecked") Class<? extends HttpController> clazz = (Class<? extends HttpController>) classLoader .loadClass(className); registry.setClazz(clazz); registerController(clazz); addController(registry); } catch (ClassNotFoundException e) { logger.error(e.getMessage()); } } private void registerWebserver(HapporWebserver server) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(HapporWebserver.class); builder.addPropertyValue("port", server.getPort()); builder.addPropertyValue("timeout", server.getTimeout()); builder.addPropertyValue("maxHttpSize", server.getMaxHttpSize()); builder.addPropertyValue("executeThreads", server.getExecuteThreads()); BeanDefinition beanDefinition = builder.getBeanDefinition(); BeanDefinitionRegistry factory = (BeanDefinitionRegistry) ctx.getBeanFactory(); factory.registerBeanDefinition("server", beanDefinition); } private void registerHandler(Class<WebserverHandler> clazz) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(clazz); BeanDefinition beanDefinition = builder.getBeanDefinition(); BeanDefinitionRegistry factory = (BeanDefinitionRegistry) ctx.getBeanFactory(); factory.registerBeanDefinition("handler", beanDefinition); } private void registerController(Class<? extends HttpController> clazz) { String name = "controller#" + getControllers().size(); BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(clazz); BeanDefinition beanDefinition = builder.getBeanDefinition(); beanDefinition.setScope("prototype"); BeanDefinitionRegistry factory = (BeanDefinitionRegistry) ctx.getBeanFactory(); factory.registerBeanDefinition(name, beanDefinition); } }