package br.com.caelum.guj.vraptor.filter; import java.io.IOException; 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.apache.log4j.Logger; import br.com.caelum.guj.repositories.TopicRepository; import br.com.caelum.guj.repositories.TopicRepositoryWrapper; import br.com.caelum.guj.uri.DefaultBookmarkableURIBuilder; import br.com.caelum.guj.uri.DefaultURICache; import br.com.caelum.guj.uri.URICache; import br.com.caelum.guj.uri.compatible.CompatibleToBookmarkablePostConverter; import br.com.caelum.guj.view.Slugger; public class CompatibleURIFilter implements Filter { private static Logger LOG = Logger.getLogger(CompatibleURIFilter.class); private TopicRepository topicRepository; private URICache cache; @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; String requestURI = request.getRequestURI(); String cachedBookmarkableUri = cache.getBookmarkableURI(requestURI); if (cachedBookmarkableUri != null) { LOG.debug("Using cache to redirect to " + cachedBookmarkableUri); redirectTo(response, cachedBookmarkableUri); return; } String newBookmarkableUri = compatibleURIToBookmarkableURI(requestURI, request); if (newBookmarkableUri != null) { redirectTo(response, newBookmarkableUri); cache.put(requestURI, newBookmarkableUri); LOG.debug("Caching " + newBookmarkableUri); return; } chain.doFilter(req, res); } private String compatibleURIToBookmarkableURI(String compatibleURI, HttpServletRequest request) { CompatibleToBookmarkablePostConverter converter = new CompatibleToBookmarkablePostConverter(compatibleURI, topicRepository, new DefaultBookmarkableURIBuilder(new Slugger())); if (converter.isConvertable()) { return request.getContextPath() + converter.convert(); } return null; } private void redirectTo(HttpServletResponse response, String newUri) { response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); response.setHeader("Location", newUri); } @Override public void destroy() { cache.removeCache(); } @Override public void init(FilterConfig config) throws ServletException { createTopicRepository(config); createURICache(config); } private void createTopicRepository(FilterConfig config) throws ServletException { String topicRepositoryClassName = config.getInitParameter("topicRepository"); if (topicRepositoryClassName == null) { topicRepository = new TopicRepositoryWrapper(); } else { try { topicRepository = (TopicRepository) Class.forName(topicRepositoryClassName).newInstance(); } catch (Exception e) { throw new ServletException(e); } } } private void createURICache(FilterConfig config) throws ServletException { URICache cacheFromContext = (URICache) config.getServletContext().getAttribute("URICache"); if (cacheFromContext == null) { cache = new DefaultURICache(); config.getServletContext().setAttribute("URICache", cache); } else { this.cache = cacheFromContext; } } }