package org.ireland.jnetty.config; import java.io.BufferedReader; import java.io.FileReader; import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Set; import javax.servlet.DispatcherType; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.ireland.jnetty.dispatch.filter.FilterConfigImpl; import org.ireland.jnetty.dispatch.servlet.ServletConfigImpl; import org.ireland.jnetty.webapp.WebApp; import org.springframework.util.Assert; /** * A Loader to parse web.xml FilterConfig ,ServletConfig * * 加载 配置文件[web.xml] * * @author KEN * */ public class WebXmlLoader { private static final Log log = LogFactory.getLog(WebXmlLoader.class); private static String FILE_PATH; private Document doc; private final WebApp webApp; public WebXmlLoader(WebApp webApp) { Assert.notNull(webApp); this.webApp = webApp; FILE_PATH = webApp.getRealPath("/WEB-INF/web.xml"); StringBuilder builder = new StringBuilder(); try { String line; BufferedReader reader = new BufferedReader( new FileReader(FILE_PATH)); while((line = reader.readLine()) != null) { builder.append(line); } String xmlString = builder.toString(); doc = DocumentHelper.parseText(xmlString); } catch (Exception e1) { e1.printStackTrace(); } if (log.isDebugEnabled()) { log.debug(FILE_PATH + " is loaded."); } } /** * 加载 <context-param> 标签 */ public void loadInitParam() { log.debug("loading <context-param>."); Element rootElt = doc.getRootElement(); // 获取根节点 Iterator iter = rootElt.elementIterator("context-param"); // 获取根节点下的子节点context-param // 遍历context-param节点 while (iter.hasNext()) { Element recordEle = (Element) iter.next(); String name = recordEle.elementTextTrim("param-name"); // 拿到context-param节点下的子节点param-name值 String value = recordEle.elementTextTrim("param-value"); // webApp.setInitParameter(name, value); } } /** * 加载<listener>标签 */ public void loadListener() { log.debug("loading <listener>"); Element rootElt = doc.getRootElement(); // 获取根节点 Iterator iter = rootElt.elementIterator("listener"); // 获取根节点下的子节点listener // 遍历listener节点 while (iter.hasNext()) { Element recordEle = (Element) iter.next(); String name = recordEle.elementTextTrim("listener-class"); webApp.addListener(name); } } /** * 解释web.xml所有的<filter>元素,并返回一个<filterName,FilterConfigImpl>的map * * @return * @throws ClassNotFoundException */ public LinkedHashMap<String, FilterConfigImpl> praseFilter() throws ClassNotFoundException { log.debug("loading <filter>."); Element rootElt = doc.getRootElement(); // 获取根节点 Iterator iter = rootElt.elementIterator("filter"); // 获取根节点下的子节点<filter> LinkedHashMap<String, FilterConfigImpl> filterMap = new LinkedHashMap<String, FilterConfigImpl>(); // 遍历context-param节点 while (iter.hasNext()) { Element recordEle = (Element) iter.next(); String filterName = recordEle.elementTextTrim("filter-name"); // 拿到context-param节点下的子节点param-name值 FilterConfigImpl config = webApp.createNewFilterConfig(); config.setFilterName(filterName); String filterClassName = recordEle.elementTextTrim("filter-class"); // if (filterClassName == null || filterClassName.isEmpty()) throw new ConfigException("<filter-class> can not be empty"); config.setFilterClass(filterClassName); config.setAsyncSupported(Boolean.parseBoolean(recordEle.elementTextTrim("async-supported"))); config.setDescription(recordEle.elementTextTrim("description")); config.setDisplayName(recordEle.elementTextTrim("display-name")); Iterator innerIter = recordEle.elementIterator("init-param"); //<init-param> while (innerIter.hasNext()) { Element innerEle = (Element) innerIter.next(); String name = innerEle.elementTextTrim("param-name"); String value = innerEle.elementTextTrim("param-value"); config.addInitParam(name, value); } // filterMap.put(filterName, config); } return filterMap; } /** * 1:调用praseFilter()取得所有filter 2:按顺序解释每个<filter-mapping>元素,在filterMap中找到对应的FilterConfigImpl,并配置到webApp中 * * @throws ClassNotFoundException */ public void parseFilterMapping(LinkedHashMap<String, FilterConfigImpl> filterMap) throws ClassNotFoundException { log.debug("loading <filter-mapping>."); Element rootElt = doc.getRootElement(); // 获取根节点 Iterator iter = rootElt.elementIterator("filter-mapping"); // 获取根节点下的子节点<filter-mapping> while (iter.hasNext()) { Element recordEle = (Element) iter.next(); String filterName = recordEle.elementTextTrim("filter-name"); FilterConfigImpl config = filterMap.get(filterName); if (config == null) throw new ConfigException("the <filter> element with name[" + filterName + "] is not exist."); // <filter-mapping>可以包含多个 <url-pattern> Set<String> urlPatterns = new HashSet<String>(); Iterator innerIter = recordEle.elementIterator("url-pattern"); //<filter-mapping> while (innerIter.hasNext()) { Element innerEle = (Element) innerIter.next(); urlPatterns.add(innerEle.getTextTrim()); } // <filter-mapping>可以包含多个 <servlet-name> Set<String> servletNames = new HashSet<String>(); innerIter = recordEle.elementIterator("servlet-name"); //<filter-mapping> while (innerIter.hasNext()) { Element innerEle = (Element) innerIter.next(); servletNames.add(innerEle.getTextTrim()); } // 查找这个Filter的所有"<dispatcher>"标签,一个<filter-mapping>可以包含多个<dispatcher>标签 Set<DispatcherType> dispatcherTypes = new HashSet<DispatcherType>(); innerIter = recordEle.elementIterator("dispatcher"); //<filter-mapping> while (innerIter.hasNext()) { Element innerEle = (Element) innerIter.next(); dispatcherTypes.add(DispatcherType.valueOf(innerEle.getTextTrim())); } // 查找<filter-mapping>的所有<servlet-name>标签,一个<servlet-name>可以包含多个<servlet-name>标签 if (urlPatterns.size() > 0) { config.addMappingForUrlPatterns(dispatcherTypes.size() == 0 ? null : EnumSet.copyOf(dispatcherTypes), true, toArray(urlPatterns)); } if (servletNames.size() > 0) { config.addMappingForServletNames(dispatcherTypes.size() == 0 ? null : EnumSet.copyOf(dispatcherTypes), true, toArray(servletNames)); } } } /** * 解释web.xml中的<servlet>标签 * * @throws ClassNotFoundException */ public LinkedHashMap<String, ServletConfigImpl> praseServletConfig() throws ClassNotFoundException { log.debug("loading <servlet>."); Element rootElt = doc.getRootElement(); // 获取根节点 Iterator iter = rootElt.elementIterator("servlet"); // 获取根节点下的子节点<servlet> LinkedHashMap<String, ServletConfigImpl> servletMap = new LinkedHashMap<String, ServletConfigImpl>(); // 遍历<servlet>节点 while (iter.hasNext()) { Element recordEle = (Element) iter.next(); String servletName = recordEle.elementTextTrim("servlet-name"); // 拿到context-param节点下的子节点param-name值 ServletConfigImpl config = webApp.createNewServletConfig(); config.setServletName(servletName); String className = recordEle.elementTextTrim("servlet-class"); // if (className == null || className.isEmpty()) throw new ConfigException("<servlet-class> can not be empty"); config.setServletClass(className); config.setAsyncSupported(Boolean.parseBoolean(recordEle.elementTextTrim("async-supported"))); config.setDescription(recordEle.elementTextTrim("description")); config.setDisplayName(recordEle.elementTextTrim("display-name")); String loadOnStartup = recordEle.elementTextTrim("load-on-startup"); if(loadOnStartup != null) config.setLoadOnStartup(Integer.parseInt(loadOnStartup)); Iterator innerIter = recordEle.elementIterator("init-param"); //<init-param> while (innerIter.hasNext()) { Element innerEle = (Element) innerIter.next(); String name = innerEle.elementTextTrim("param-name"); String value = innerEle.elementTextTrim("param-value"); config.setInitParam(name, value); } // servletMap.put(servletName, config); } return servletMap; } public void parseServletMapping(LinkedHashMap<String, ServletConfigImpl> servletMap) throws ClassNotFoundException { log.debug("loading <servlet-mapping>."); /** * find <servlet-mapping> for <servlet> 查找 当前<servlet>标签 所关联 的所有 "<servlet-mapping>"标签 */ Element rootElt = doc.getRootElement(); // 获取根节点 Iterator iter = rootElt.elementIterator("servlet-mapping"); // 获取根节点下的子节点<servlet-mapping> // 遍历<servlet>节点 while (iter.hasNext()) { Element recordEle = (Element) iter.next(); String servletName = recordEle.elementTextTrim("servlet-name"); ServletConfigImpl config = servletMap.get(servletName); if (config == null) throw new ConfigException("the <servlet> element with name[" + servletName + "] is not exist."); String value; // 一个<servlet-mapping>可以包含多个 <url-pattern> Set<String> urlPatterns = new HashSet<String>(); Iterator innerIter = recordEle.elementIterator("url-pattern"); //<filter-mapping> while (innerIter.hasNext()) { Element innerEle = (Element) innerIter.next(); urlPatterns.add(innerEle.getTextTrim()); } if (urlPatterns.size() > 0) { config.addMapping(toArray(urlPatterns)); // 添加<servlet-mapping> } } } // util private static <E> String[] toArray(Collection<String> c) { String[] array = new String[c.size()]; int i = 0; for (String e : c) { array[i] = e; i++; } return array; } }