package org.nutz.mvc;

import java.io.IOException;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.nutz.lang.Strings;
import org.nutz.mvc.config.FilterNutConfig;

/**
 * 同 JSP/Serlvet 容器的挂接点
 * 
 * @author zozoh(zozohtnt@gmail.com)
 * @author juqkai(juqkai@gmail.com)
 * @author wendal(wendal1985@gmail.com)
 */
public class NutFilter implements Filter {

	private ActionHandler handler;

	private static final String IGNORE = "^.+\\.(jsp|png|gif|jpg|js|css|jspx|jpeg|swf)$";

	private Pattern ignorePtn;

	private boolean skipMode;

	public void init(FilterConfig conf) throws ServletException {
		FilterNutConfig config = new FilterNutConfig(conf);
		// 如果仅仅是用来更新 Message 字符串的，不加载 Nutz.Mvc 设定
		// @see Issue 301
		String skipMode = Strings.sNull(conf.getInitParameter("skip-mode"), "false").toLowerCase();
		if (!"true".equals(skipMode)) {
			handler = new ActionHandler(config);
			String regx = Strings.sNull(config.getInitParameter("ignore"), IGNORE);
			if (!"null".equalsIgnoreCase(regx)) {
				ignorePtn = Pattern.compile(regx, Pattern.CASE_INSENSITIVE);
			}
		} else
			this.skipMode = true;
	}

	public void destroy() {
		if(handler !=null)
			handler.depose();
	}

	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException {
		if (!skipMode) {
			RequestPath path = Mvcs.getRequestPathObject((HttpServletRequest) req);
			if (null == ignorePtn || !ignorePtn.matcher(path.getUrl()).find()) {
				if (handler.handle((HttpServletRequest) req, (HttpServletResponse) resp))
					return;
			}
		}
		// 更新 Request 必要的属性
		else {
			Mvcs.updateRequestAttributes((HttpServletRequest) req);
		}
		// 本过滤器没有找到入口函数，继续其他的过滤器
		chain.doFilter(req, resp);
	}
}

@@ -860,16 +860,90 @@
 ipMode;%0D
+%0A%09%0D%0A%09//%E8%AF%B7%E6%B1%82%E6%9C%89%E5%AF%B9%E5%BA%94%E7%9A%84Action,%E5%A4%84%E7%90%86%E5%AE%8C%E6%88%90%E5%90%8E,%E6%98%AF%E5%90%A6%E7%BB%A7%E7%BB%AD%E6%89%A7%E8%A1%8C%E4%B8%8B%E4%B8%80%E4%B8%AAFilter%0D%0A%09private boolean doNextFilter;%0D
 %0A%0D%0A%09publ
@@ -1519,16 +1519,169 @@
  true;%0D%0A
+%09%09%0D%0A%09%09String doNextFilter = Strings.sNull(conf.getInitParameter(%22do-next%22), %22false%22).toLowerCase();%0D%0A%09%09this.doNextFilter = %22true%22.equals(doNextFilter);%0D%0A
 %09%7D%0D%0A%0D%0A%09p
@@ -2138,33 +2138,109 @@
 %09%09%09%09
-return;%0D%0A%09%09%09%7D%0D%0A%09%09%7D%0D%0A%09%09// 
+if (!doNextFilter)%0D%0A%09%09%09%09%09%09return;%0D%0A%09%09%09%7D%0D%0A%09%09%7D%0D%0A%09%09// %E5%A6%82%E6%9E%9C%E5%B7%B2%E7%BB%8F%E6%89%BE%E5%88%B0%E5%AF%B9%E5%BA%94%E7%9A%84action,%E8%80%8C%E4%B8%94%E6%AD%A3%E7%A1%AE%E5%A4%84%E7%90%86,%E5%B9%B6%E4%B8%94%E4%B8%8D%E6%98%AFdonext%E6%A8%A1%E5%BC%8F,%E9%82%A3%E4%B9%88%E4%B8%8D%E4%BC%9A%E8%B5%B0%E5%88%B0%E8%BF%99%E9%87%8C%0D%0A%09%09//
 %E6%9B%B4%E6%96%B0 R
@@ -2257,19 +2257,8 @@
 %E5%B1%9E%E6%80%A7%0D%0A
-%09%09else %7B%0D%0A%09
 %09%09Mv
@@ -2312,21 +2312,16 @@
  req);%0D%0A
-%09%09%7D%0D%0A
 %09%09// %E6%9C%AC%E8%BF%87%E6%BB%A4

Fix Issue 429 , Fix issue 340