001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry;
016    
017    import java.io.IOException;
018    
019    import javax.servlet.Filter;
020    import javax.servlet.FilterChain;
021    import javax.servlet.FilterConfig;
022    import javax.servlet.ServletException;
023    import javax.servlet.ServletRequest;
024    import javax.servlet.ServletResponse;
025    import javax.servlet.http.HttpServletRequest;
026    import javax.servlet.http.HttpServletResponse;
027    
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    import org.apache.hivemind.HiveMind;
031    
032    /**
033     * Filter used to redirect a root context URL (i.e., "/context" or "/context/" to the Tapestry
034     * application servlet (typically, "/context/app"). This servlet is mapped to "/" and must have a
035     * &lt;init-parameter&;gt; <code>redirect-path</code> that is the application servlet's path
036     * (i.e., "/app"). If no value is specified, then "/app" is used. The path is always relative to the
037     * servlet context, and should always begin with a leading slash.
038     * <p>
039     * Filters are only available in Servlet API 2.3 and above.
040     * <p>
041     * Servlet API 2.4 is expected to allow a servlets in the welcome list (equivalent to index.html or
042     * index.jsp), at which point this filter should no longer be necessary.
043     * 
044     * @author Howard Lewis Ship
045     * @since 3.0
046     */
047    
048    public class RedirectFilter implements Filter
049    {
050        private static final Log LOG = LogFactory.getLog(RedirectFilter.class);
051    
052        public static final String REDIRECT_PATH_PARAM = "redirect-path";
053    
054        private String _redirectPath;
055    
056        public void init(FilterConfig config) throws ServletException
057        {
058            _redirectPath = config.getInitParameter(REDIRECT_PATH_PARAM);
059    
060            if (HiveMind.isBlank(_redirectPath))
061                _redirectPath = "/app";
062    
063            if (LOG.isDebugEnabled())
064                LOG.debug(Tapestry.format("RedirectServlet.redirect-path", _redirectPath));
065        }
066    
067        public void destroy()
068        {
069    
070        }
071    
072        /**
073         * This filter intercepts the so-called "default" servlet, whose job is to provide access to
074         * standard resources packaged within the web application context. This code is interested in
075         * only the very root, redirecting to the appropriate Tapestry application servlet. Other values
076         * are passed through unchanged.
077         */
078        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
079                throws IOException, ServletException
080        {
081            HttpServletRequest hrequest = (HttpServletRequest) request;
082            HttpServletResponse hresponse = (HttpServletResponse) response;
083    
084            String servletPath = hrequest.getServletPath();
085            String pathInfo = hrequest.getPathInfo();
086    
087            // Been experimenting with different servlet containers. In Jetty 4.2.8 and Tomcat 4.1,
088            // resources have a non-null servletPath. If JBossWeb 3.0.6, the servletPath is
089            // null and the pathInfo indicates the relative location of the resource.
090    
091            if ((HiveMind.isBlank(servletPath) || servletPath.equals("/"))
092                    && (HiveMind.isBlank(pathInfo) || pathInfo.equals("/")))
093            {
094                String path = hrequest.getContextPath() + _redirectPath;
095    
096                if (LOG.isDebugEnabled())
097                    LOG.debug(Tapestry.format("RedirectServlet.redirecting", path));
098    
099                hresponse.sendRedirect(path);
100                return;
101            }
102    
103            chain.doFilter(request, response);
104        }
105    
106    }