package org.jboss.seam.web; import static org.jboss.seam.ScopeType.APPLICATION; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.servlet.FilterChain; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.jboss.seam.Seam; import org.jboss.seam.annotations.Install; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; import org.jboss.seam.annotations.intercept.BypassInterceptors; import org.jboss.seam.annotations.web.Filter; import org.jboss.seam.log.LogProvider; import org.jboss.seam.log.Logging; import org.jboss.seam.navigation.Page; import org.jboss.seam.navigation.Pages; @Scope(APPLICATION) @Name("org.jboss.seam.web.rewriteFilter") @Install(precedence=Install.BUILT_IN,value=false) @BypassInterceptors @Filter(within={"org.jboss.seam.web.multipartFilter","org.jboss.seam.web.authenticationFilter","org.jboss.seam.web.loggingFilter","org.jboss.seam.web.exceptionFilter","org.jboss.seam.web.identityFilter"}) public class RewriteFilter extends AbstractFilter { private static LogProvider log = Logging.getLogProvider(RewriteFilter.class); private String viewMapping; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { List<Pattern> allPatterns = getAllPatterns(); boolean done = false; if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) { response = new RewritingResponse((HttpServletRequest) request, (HttpServletResponse)response, allPatterns); done = process((HttpServletRequest) request, (HttpServletResponse) response, allPatterns); } if (!done) { chain.doFilter(request, response); } } @SuppressWarnings("unchecked") public boolean process(HttpServletRequest request, HttpServletResponse response, List<Pattern> patterns) throws IOException, ServletException { String fullPath = request.getRequestURI(); //log.debug("incoming URL is " + fullPath); //log.debug("known patterns are " + patterns); String localPath = strip(fullPath, request.getContextPath()); Rewrite rewrite = matchPatterns(localPath, patterns); if (rewrite!=null) { String newPath = rewrite.rewrite(); //log.debug("rewritten incoming path is " + newPath); if (!fullPath.equals(request.getContextPath() + newPath)) { RequestDispatcher dispatcher = request.getRequestDispatcher(newPath); // final String wrappedPath = newPath; // HttpServletRequest wrapped = new HttpServletRequestWrapper(request) { // @Override // public String getServletPath() { // return wrappedPath; // // } // }; // dispatcher.forward(wrapped, response); dispatcher.forward(request, response); return true; } } return false; } private Rewrite matchPatterns(String localPath, List<Pattern> patterns) { for (Pattern pattern: patterns) { Rewrite rewrite = pattern.matchIncoming(localPath); if (rewrite!=null && rewrite.isMatch()) { return rewrite; } } return null; } private String strip(String fullPath, String contextPath) { if (fullPath.startsWith(contextPath)) { return fullPath.substring(contextPath.length()); } else { return fullPath; } } private List<Pattern> getAllPatterns() { List<Pattern> allPatterns = new ArrayList<Pattern>(); Pages pages = (Pages) getServletContext().getAttribute(Seam.getComponentName(Pages.class)); if (pages != null) { Collection<String> ids = pages.getKnownViewIds(); for (String id: ids) { Page page = pages.getPage(id); allPatterns.addAll(page.getRewritePatterns()); } } else { log.warn("Pages is null for incoming request!"); } ServletMapping mapping = new ServletMapping(getViewMapping()); for (Pattern pattern: allPatterns) { pattern.setViewMapping(mapping); } return allPatterns; } public String getViewMapping() { return viewMapping == null ? "*.seam" : viewMapping; } public void setViewMapping(String viewMapping) { this.viewMapping = viewMapping; } }