Author: markt Date: Mon Apr 11 10:08:37 2016 New Revision: 1738562 URL: http://svn.apache.org/viewvc?rev=1738562&view=rev Log: Update the implementation of the the proposed Servlet 4.0 API to provide mapping type information for the current request to reflect discussions within the EG.
Modified: tomcat/trunk/java/javax/servlet/RequestDispatcher.java tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java tomcat/trunk/java/javax/servlet/http/Mapping.java tomcat/trunk/java/javax/servlet/http/MappingMatch.java tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java tomcat/trunk/java/org/apache/catalina/core/ApplicationDispatcher.java tomcat/trunk/java/org/apache/catalina/core/ApplicationHttpRequest.java tomcat/trunk/java/org/apache/catalina/core/ApplicationMapping.java tomcat/trunk/java/org/apache/catalina/core/ApplicationRequest.java tomcat/trunk/test/org/apache/catalina/core/TestApplicationMapping.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/javax/servlet/RequestDispatcher.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/javax/servlet/RequestDispatcher.java?rev=1738562&r1=1738561&r2=1738562&view=diff ============================================================================== --- tomcat/trunk/java/javax/servlet/RequestDispatcher.java (original) +++ tomcat/trunk/java/javax/servlet/RequestDispatcher.java Mon Apr 11 10:08:37 2016 @@ -93,6 +93,17 @@ public interface RequestDispatcher { /** * The name of the request attribute that should be set by the container + * when the {@link #forward(ServletRequest, ServletResponse)} method is + * called. It provides the original value of a path-related property of the + * request. See the chapter "Forwarded Request Parameters" in the Servlet + * Specification for details. + * + * @since Servlet 4.0 + */ + static final String FORWARD_MAPPING = "javax.servlet.forward.mapping"; + + /** + * The name of the request attribute that should be set by the container * when the {@link #include(ServletRequest, ServletResponse)} method is * called on the {@code RequestDispatcher} obtained by a path and not by a * name. It provides information on the path that was used to obtain the @@ -153,6 +164,18 @@ public interface RequestDispatcher { /** * The name of the request attribute that should be set by the container + * when the {@link #include(ServletRequest, ServletResponse)} method is + * called on the {@code RequestDispatcher} obtained by a path and not by a + * name. It provides information on the path that was used to obtain the + * {@code RequestDispatcher} instance for this include call. See the chapter + * "Included Request Parameters" in the Servlet Specification for details. + * + * @since Servlet 4.0 + */ + static final String INCLUDE_MAPPING = "javax.servlet.include.mapping"; + + /** + * The name of the request attribute that should be set by the container * when custom error-handling servlet or JSP page is invoked. The value of * the attribute is of type {@code java.lang.Throwable}. See the chapter * "Error Handling" in the Servlet Specification for details. Modified: tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java?rev=1738562&r1=1738561&r2=1738562&view=diff ============================================================================== --- tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java (original) +++ tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java Mon Apr 11 10:08:37 2016 @@ -184,9 +184,14 @@ public interface HttpServletRequest exte } @Override - public MappingMatch getMatchType() { + public MappingMatch getMappingMatch() { return MappingMatch.UNKNOWN; } + + @Override + public String getServletName() { + return ""; + } }; } Modified: tomcat/trunk/java/javax/servlet/http/Mapping.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/javax/servlet/http/Mapping.java?rev=1738562&r1=1738561&r2=1738562&view=diff ============================================================================== --- tomcat/trunk/java/javax/servlet/http/Mapping.java (original) +++ tomcat/trunk/java/javax/servlet/http/Mapping.java Mon Apr 11 10:08:37 2016 @@ -16,6 +16,8 @@ */ package javax.servlet.http; +import javax.servlet.annotation.WebServlet; + /** * Represents how the request from which this object was obtained was mapped to * the associated servlet. @@ -38,5 +40,14 @@ public interface Mapping { /** * @return The type of match ({@link MappingMatch#UNKNOWN} if not known) */ - MappingMatch getMatchType(); + MappingMatch getMappingMatch(); + + /** + * @return The name of the servlet (as specified in web.xml, + * {@link WebServlet#name()}, + * {@link javax.servlet.ServletContext#addServlet(String, Class)} or + * one of the other <code>addServlet()</code> methods) that the + * request was mapped to. + */ + String getServletName(); } Modified: tomcat/trunk/java/javax/servlet/http/MappingMatch.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/javax/servlet/http/MappingMatch.java?rev=1738562&r1=1738561&r2=1738562&view=diff ============================================================================== --- tomcat/trunk/java/javax/servlet/http/MappingMatch.java (original) +++ tomcat/trunk/java/javax/servlet/http/MappingMatch.java Mon Apr 11 10:08:37 2016 @@ -27,7 +27,6 @@ public enum MappingMatch { DEFAULT, EXACT, EXTENSION, - IMPLICIT, PATH, UNKNOWN } Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java?rev=1738562&r1=1738561&r2=1738562&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java Mon Apr 11 10:08:37 2016 @@ -52,6 +52,7 @@ import javax.servlet.descriptor.JspConfi import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionIdListener; import javax.servlet.http.HttpSessionListener; +import javax.servlet.http.Mapping; import org.apache.catalina.Container; import org.apache.catalina.Context; @@ -375,7 +376,7 @@ public class ApplicationContext if (wrapper == null) return (null); - return new ApplicationDispatcher(wrapper, null, null, null, null, name); + return new ApplicationDispatcher(wrapper, null, null, null, null, null, name); } @@ -460,13 +461,14 @@ public class ApplicationContext Wrapper wrapper = mappingData.wrapper; String wrapperPath = mappingData.wrapperPath.toString(); String pathInfo = mappingData.pathInfo.toString(); + Mapping mapping = (new ApplicationMapping(mappingData)).getMapping(); mappingData.recycle(); // Construct a RequestDispatcher to process this request return new ApplicationDispatcher (wrapper, uriCC.toString(), wrapperPath, pathInfo, - queryString, null); + queryString, mapping, null); } Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationDispatcher.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationDispatcher.java?rev=1738562&r1=1738561&r2=1738562&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/ApplicationDispatcher.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/ApplicationDispatcher.java Mon Apr 11 10:08:37 2016 @@ -34,6 +34,7 @@ import javax.servlet.ServletResponseWrap import javax.servlet.UnavailableException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.Mapping; import org.apache.catalina.AsyncDispatcher; import org.apache.catalina.Context; @@ -199,12 +200,13 @@ final class ApplicationDispatcher implem * (if any) * @param queryString Query string parameters included with this request * (if any) + * @param mapping The mapping for this resource (if any) * @param name Servlet name (if a named dispatcher was created) * else <code>null</code> */ public ApplicationDispatcher (Wrapper wrapper, String requestURI, String servletPath, - String pathInfo, String queryString, String name) { + String pathInfo, String queryString, Mapping mapping, String name) { super(); @@ -215,6 +217,7 @@ final class ApplicationDispatcher implem this.servletPath = servletPath; this.pathInfo = pathInfo; this.queryString = queryString; + this.mapping = mapping; this.name = name; } @@ -258,6 +261,12 @@ final class ApplicationDispatcher implem /** + * The mapping for this RequestDispatcher. + */ + private final Mapping mapping; + + + /** * The StringManager for this package. */ private static final StringManager sm = StringManager.getManager(Constants.Package); @@ -349,8 +358,7 @@ final class ApplicationDispatcher implem (ApplicationHttpRequest) wrapRequest(state); String contextPath = context.getPath(); HttpServletRequest hrequest = state.hrequest; - if (hrequest.getAttribute( - RequestDispatcher.FORWARD_REQUEST_URI) == null) { + if (hrequest.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI) == null) { wrequest.setAttribute(RequestDispatcher.FORWARD_REQUEST_URI, hrequest.getRequestURI()); wrequest.setAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH, @@ -361,6 +369,7 @@ final class ApplicationDispatcher implem hrequest.getPathInfo()); wrequest.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING, hrequest.getQueryString()); + wrequest.setAttribute(RequestDispatcher.FORWARD_MAPPING, hrequest.getMapping()); } wrequest.setContextPath(contextPath); @@ -371,6 +380,7 @@ final class ApplicationDispatcher implem wrequest.setQueryString(queryString); wrequest.setQueryParams(queryString); } + wrequest.setMapping(mapping); processRequest(request,response,state); } @@ -560,6 +570,9 @@ final class ApplicationDispatcher implem queryString); wrequest.setQueryParams(queryString); } + if (mapping != null) { + wrequest.setAttribute(RequestDispatcher.INCLUDE_MAPPING, mapping); + } wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.INCLUDE); Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationHttpRequest.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationHttpRequest.java?rev=1738562&r1=1738561&r2=1738562&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/ApplicationHttpRequest.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/ApplicationHttpRequest.java Mon Apr 11 10:08:37 2016 @@ -33,6 +33,7 @@ import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpSession; +import javax.servlet.http.Mapping; import javax.servlet.http.PushBuilder; import org.apache.catalina.Context; @@ -75,11 +76,13 @@ class ApplicationHttpRequest extends Htt RequestDispatcher.INCLUDE_SERVLET_PATH, RequestDispatcher.INCLUDE_PATH_INFO, RequestDispatcher.INCLUDE_QUERY_STRING, + RequestDispatcher.INCLUDE_MAPPING, RequestDispatcher.FORWARD_REQUEST_URI, RequestDispatcher.FORWARD_CONTEXT_PATH, RequestDispatcher.FORWARD_SERVLET_PATH, RequestDispatcher.FORWARD_PATH_INFO, - RequestDispatcher.FORWARD_QUERY_STRING }; + RequestDispatcher.FORWARD_QUERY_STRING, + RequestDispatcher.FORWARD_MAPPING}; // ----------------------------------------------------------- Constructors @@ -182,6 +185,12 @@ class ApplicationHttpRequest extends Htt /** + * The mapping for this request. + */ + private Mapping mapping = null; + + + /** * The currently active session for this request. */ protected Session session = null; @@ -510,6 +519,12 @@ class ApplicationHttpRequest extends Htt } + @Override + public Mapping getMapping() { + return mapping; + } + + /** * Return the session associated with this Request, creating one * if necessary. @@ -689,7 +704,7 @@ class ApplicationHttpRequest extends Htt queryString = request.getQueryString(); requestURI = request.getRequestURI(); servletPath = request.getServletPath(); - + mapping = request.getMapping(); } @@ -747,6 +762,12 @@ class ApplicationHttpRequest extends Htt this.queryParamString = queryString; } + + void setMapping(Mapping mapping) { + this.mapping = mapping; + } + + // ------------------------------------------------------ Protected Methods /** Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationMapping.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationMapping.java?rev=1738562&r1=1738561&r2=1738562&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/ApplicationMapping.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/ApplicationMapping.java Mon Apr 11 10:08:37 2016 @@ -35,31 +35,33 @@ public class ApplicationMapping { if (mapping == null) { switch (mappingData.matchType) { case CONTEXT_ROOT: - mapping = new MappingImpl("", "", mappingData.matchType); + mapping = new MappingImpl("", "", mappingData.matchType, + mappingData.wrapper.getName()); break; case DEFAULT: - mapping = new MappingImpl("/", "/", mappingData.matchType); + mapping = new MappingImpl("/", "/", mappingData.matchType, + mappingData.wrapper.getName()); break; case EXACT: mapping = new MappingImpl(mappingData.wrapperPath.toString(), - mappingData.wrapperPath.toString(), mappingData.matchType); + mappingData.wrapperPath.toString(), mappingData.matchType, + mappingData.wrapper.getName()); break; case EXTENSION: String path = mappingData.wrapperPath.toString(); int extIndex = path.lastIndexOf('.'); mapping = new MappingImpl(path.substring(0, extIndex), - "*" + path.substring(extIndex), mappingData.matchType); + "*" + path.substring(extIndex), mappingData.matchType, + mappingData.wrapper.getName()); break; case PATH: mapping = new MappingImpl(mappingData.pathInfo.toString(), mappingData.wrapperPath.toString() + "/*", - mappingData.matchType); + mappingData.matchType, mappingData.wrapper.getName()); break; - case IMPLICIT: - // Treat IMPLICIT as UNKNOWN since Tomcat doesn't use - // implicit mappings case UNKNOWN: - mapping = new MappingImpl("", "", mappingData.matchType); + mapping = new MappingImpl("", "", mappingData.matchType, + mappingData.wrapper.getName()); break; } } @@ -76,11 +78,14 @@ public class ApplicationMapping { private final String matchValue; private final String pattern; private final MappingMatch mappingType; + private final String servletName; - public MappingImpl(String matchValue, String pattern, MappingMatch mappingType) { + public MappingImpl(String matchValue, String pattern, MappingMatch mappingType, + String servletName) { this.matchValue = matchValue; this.pattern = pattern; this.mappingType = mappingType; + this.servletName = servletName; } @Override @@ -94,8 +99,13 @@ public class ApplicationMapping { } @Override - public MappingMatch getMatchType() { + public MappingMatch getMappingMatch() { return mappingType; } + + @Override + public String getServletName() { + return servletName; + } } } Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationRequest.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationRequest.java?rev=1738562&r1=1738561&r2=1738562&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/ApplicationRequest.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/ApplicationRequest.java Mon Apr 11 10:08:37 2016 @@ -57,11 +57,13 @@ class ApplicationRequest extends Servlet RequestDispatcher.INCLUDE_SERVLET_PATH, RequestDispatcher.INCLUDE_PATH_INFO, RequestDispatcher.INCLUDE_QUERY_STRING, + RequestDispatcher.INCLUDE_MAPPING, RequestDispatcher.FORWARD_REQUEST_URI, RequestDispatcher.FORWARD_CONTEXT_PATH, RequestDispatcher.FORWARD_SERVLET_PATH, RequestDispatcher.FORWARD_PATH_INFO, - RequestDispatcher.FORWARD_QUERY_STRING }; + RequestDispatcher.FORWARD_QUERY_STRING, + RequestDispatcher.FORWARD_MAPPING}; // ----------------------------------------------------------- Constructors Modified: tomcat/trunk/test/org/apache/catalina/core/TestApplicationMapping.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/core/TestApplicationMapping.java?rev=1738562&r1=1738561&r2=1738562&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/catalina/core/TestApplicationMapping.java (original) +++ tomcat/trunk/test/org/apache/catalina/core/TestApplicationMapping.java Mon Apr 11 10:08:37 2016 @@ -19,6 +19,7 @@ package org.apache.catalina.core; import java.io.IOException; import java.io.PrintWriter; +import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -87,6 +88,17 @@ public class TestApplicationMapping exte private void doTestMapping(String contextPath, String mapping, String requestPath, String matchValue, String matchType) throws Exception { + doTestMappingDirect(contextPath, mapping, requestPath, matchValue, matchType); + tearDown(); + setUp(); + doTestMappingInclude(contextPath, mapping, requestPath, matchValue, matchType); + tearDown(); + setUp(); + doTestMappingForward(contextPath, mapping, requestPath, matchValue, matchType); + } + + private void doTestMappingDirect(String contextPath, String mapping, String requestPath, + String matchValue, String matchType) throws Exception { Tomcat tomcat = getTomcatInstance(); // No file system docBase required @@ -103,6 +115,87 @@ public class TestApplicationMapping exte Assert.assertTrue(body, body.contains("MatchValue=[" + matchValue + "]")); Assert.assertTrue(body, body.contains("Pattern=[" + mapping + "]")); Assert.assertTrue(body, body.contains("MatchType=[" + matchType + "]")); + Assert.assertTrue(body, body.contains("ServletName=[Mapping]")); + } + + private void doTestMappingInclude(String contextPath, String mapping, String requestPath, + String matchValue, String matchType) throws Exception { + Tomcat tomcat = getTomcatInstance(); + + // No file system docBase required + Context ctx = tomcat.addContext(contextPath, null); + + Tomcat.addServlet(ctx, "Include", new IncludeServlet()); + ctx.addServletMapping(mapping, "Include"); + Tomcat.addServlet(ctx, "Mapping", new MappingServlet()); + ctx.addServletMapping("/mapping", "Mapping"); + + tomcat.start(); + + ByteChunk bc = getUrl("http://localhost:" + getPort() + contextPath + requestPath); + String body = bc.toString(); + + Assert.assertTrue(body, body.contains("MatchValue=[" + matchValue + "]")); + Assert.assertTrue(body, body.contains("Pattern=[" + mapping + "]")); + Assert.assertTrue(body, body.contains("MatchType=[" + matchType + "]")); + Assert.assertTrue(body, body.contains("ServletName=[Include]")); + + Assert.assertTrue(body, body.contains("IncludeMatchValue=[/mapping]")); + Assert.assertTrue(body, body.contains("IncludePattern=[/mapping]")); + Assert.assertTrue(body, body.contains("IncludeMatchType=[EXACT]")); + Assert.assertTrue(body, body.contains("IncludeServletName=[Mapping]")); + } + + private void doTestMappingForward(String contextPath, String mapping, String requestPath, + String matchValue, String matchType) throws Exception { + Tomcat tomcat = getTomcatInstance(); + + // No file system docBase required + Context ctx = tomcat.addContext(contextPath, null); + + Tomcat.addServlet(ctx, "Forward", new ForwardServlet()); + ctx.addServletMapping(mapping, "Forward"); + Tomcat.addServlet(ctx, "Mapping", new MappingServlet()); + ctx.addServletMapping("/mapping", "Mapping"); + + tomcat.start(); + + ByteChunk bc = getUrl("http://localhost:" + getPort() + contextPath + requestPath); + String body = bc.toString(); + + Assert.assertTrue(body, body.contains("MatchValue=[/mapping]")); + Assert.assertTrue(body, body.contains("Pattern=[/mapping]")); + Assert.assertTrue(body, body.contains("MatchType=[EXACT]")); + Assert.assertTrue(body, body.contains("ServletName=[Mapping]")); + + Assert.assertTrue(body, body.contains("ForwardMatchValue=[" + matchValue + "]")); + Assert.assertTrue(body, body.contains("ForwardPattern=[" + mapping + "]")); + Assert.assertTrue(body, body.contains("ForwardMatchType=[" + matchType + "]")); + Assert.assertTrue(body, body.contains("ForwardServletName=[Forward]")); + } + + + private static class IncludeServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + RequestDispatcher rd = req.getRequestDispatcher("/mapping"); + rd.include(req, resp); + } + } + + + private static class ForwardServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + RequestDispatcher rd = req.getRequestDispatcher("/mapping"); + rd.forward(req, resp); + } } @@ -118,7 +211,23 @@ public class TestApplicationMapping exte Mapping mapping = req.getMapping(); pw.println("MatchValue=[" + mapping.getMatchValue() + "]"); pw.println("Pattern=[" + mapping.getPattern() + "]"); - pw.println("MatchType=[" + mapping.getMatchType() + "]"); + pw.println("MatchType=[" + mapping.getMappingMatch() + "]"); + pw.println("ServletName=[" + mapping.getServletName() + "]"); + Mapping includeMapping = (Mapping) req.getAttribute(RequestDispatcher.INCLUDE_MAPPING); + if (includeMapping != null) { + pw.println("IncludeMatchValue=[" + includeMapping.getMatchValue() + "]"); + pw.println("IncludePattern=[" + includeMapping.getPattern() + "]"); + pw.println("IncludeMatchType=[" + includeMapping.getMappingMatch() + "]"); + pw.println("IncludeServletName=[" + includeMapping.getServletName() + "]"); + + } + Mapping forwardMapping = (Mapping) req.getAttribute(RequestDispatcher.FORWARD_MAPPING); + if (forwardMapping != null) { + pw.println("ForwardMatchValue=[" + forwardMapping.getMatchValue() + "]"); + pw.println("ForwardPattern=[" + forwardMapping.getPattern() + "]"); + pw.println("ForwardMatchType=[" + forwardMapping.getMappingMatch() + "]"); + pw.println("ForwardServletName=[" + forwardMapping.getServletName() + "]"); + } } } } Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1738562&r1=1738561&r2=1738562&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Mon Apr 11 10:08:37 2016 @@ -119,6 +119,11 @@ functions as designed and sessions are swapped out to keep the active session count below <code>maxActiveSessions</code>. (markt) </fix> + <update> + Update the implementation of the the proposed Servlet 4.0 API to provide + mapping type information for the current request to reflect discussions + within the EG. (markt) + </update> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org