package org.sothis.mvc.http.servlet; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Enumeration; import java.util.Properties; import javax.servlet.FilterConfig; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sothis.core.beans.BeanFactory; import org.sothis.core.config.PropertiesBean; import org.sothis.mvc.ActionContext; import org.sothis.mvc.ActionInvocationHelper; import org.sothis.mvc.ApplicationContext; import org.sothis.mvc.Configuration; import org.sothis.mvc.ConfigurationException; import org.sothis.mvc.DefaultApplicationContext; import org.sothis.mvc.Flash; import org.sothis.mvc.Request; import org.sothis.mvc.Response; /** * @param beanFactoryClass * 如果配置了configBeanName,则必须同时配置beanFactoryClass * @param configBeanName * 在beanFactory中定义的config bean名称 * @param configLocation * 如果没有配置configBeanName,则使用configLocation指身的classpath路径查找配置文件,如果没有配置, * 则默认使用sothis.properties * @author velna * */ public class ServletApplication { private static final Logger LOGGER = LoggerFactory.getLogger(ServletApplication.class); private ApplicationContext applicationContext; private ServletContext servletContext; public ServletApplication(final ServletConfig servletConfig) throws ServletException { init(new Config() { @Override public String getName() { return servletConfig.getServletName(); } @Override public ServletContext getServletContext() { return servletConfig.getServletContext(); } @Override public String getInitParameter(String name) { return servletConfig.getInitParameter(name); } @Override public Enumeration<String> getInitParameterNames() { return servletConfig.getInitParameterNames(); } }); } public ServletApplication(final FilterConfig filterConfig) throws ServletException { init(new Config() { @Override public String getName() { return filterConfig.getFilterName(); } @Override public ServletContext getServletContext() { return filterConfig.getServletContext(); } @Override public String getInitParameter(String name) { return filterConfig.getInitParameter(name); } @Override public Enumeration<String> getInitParameterNames() { return filterConfig.getInitParameterNames(); } }); } private void init(Config servletConfig) throws ServletException { if (LOGGER.isInfoEnabled()) { LOGGER.info("Sothis: initialization started"); } try { BeanFactory beanFactory = null; Configuration config; servletContext = servletConfig.getServletContext(); String beanFactoryClass = servletConfig.getInitParameter("beanFactoryClass"); if (null != beanFactoryClass) { beanFactory = createBeanFactory((Class<BeanFactory>) Class.forName(beanFactoryClass)); } String configBeanName = servletConfig.getInitParameter("configBeanName"); if (null != configBeanName) { if (null == beanFactory) { throw new ServletException("'beanFactoryClass' param must be configured since 'configBeanName' is used."); } PropertiesBean propertiesBean = beanFactory.getBean(configBeanName); config = new Configuration(propertiesBean.getProperties()); } else { String configLocation = servletConfig.getInitParameter("configLocation"); if (null == configLocation) { configLocation = "sothis.properties"; } InputStream input = Configuration.class.getClassLoader().getResourceAsStream(configLocation); if (null == input) { if (LOGGER.isWarnEnabled()) { LOGGER.warn("can not find sothi config file : {}, using sothis.default.properties as default.", configLocation); } input = Configuration.class.getClassLoader().getResourceAsStream("sothis.default.properties"); } Properties properties = new Properties(); properties.load(new InputStreamReader(input, "UTF-8")); input.close(); config = new Configuration(properties); } if (null == beanFactory) { if (null == config.getBeanFactoryClass()) { throw new ConfigurationException("sothis.beanFactory.class is not set !"); } beanFactory = createBeanFactory(config.getBeanFactoryClass()); } applicationContext = new DefaultApplicationContext(servletContext.getContextPath(), beanFactory, config, servletContext); registerBeans(config, beanFactory); if (LOGGER.isInfoEnabled()) { LOGGER.info("Sothis: initialization completed"); } } catch (Exception e) { throw new ServletException("sothis init failed: ", e); } } private void registerBeans(Configuration config, BeanFactory beanFactory) { beanFactory.registerBean(config.getFlash().getName(), config.getFlash()); } private BeanFactory createBeanFactory(Class<BeanFactory> beanFactoryClass) throws InstantiationException, IllegalAccessException { BeanFactory beanFactory = beanFactoryClass.newInstance(); if (beanFactory instanceof ServletBeanFactory) { ((ServletBeanFactory) beanFactory).init(servletContext); } return beanFactory; } public boolean execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { ActionContext context = ActionContext.getContext(); Request request = new ServletHttpRequest((HttpServletRequest) req); Response response = new ServletHttpResponse((HttpServletResponse) resp, ((HttpServletRequest) req).getProtocol()); context.setRequest(request); context.setResponse(response); context.setApplicationContext(applicationContext); Flash flash = context.getFlash(false); if (null != flash) { flash.flash(); } return ActionInvocationHelper.invoke(context, applicationContext, request, response) || resp.isCommitted(); } catch (Exception e) { throw new ServletException(e); } } private static interface Config { public String getName(); public ServletContext getServletContext(); public String getInitParameter(String name); public Enumeration<String> getInitParameterNames(); } public static Logger getLogger() { return LOGGER; } public ApplicationContext getApplicationContext() { return applicationContext; } public ServletContext getServletContext() { return servletContext; } }