Author: markt Date: Tue Mar 8 14:12:21 2016 New Revision: 1734095 URL: http://svn.apache.org/viewvc?rev=1734095&view=rev Log: As per EG discussion, implement SERVLET_SPEC-73
Added: tomcat/trunk/test/org/apache/catalina/core/TestApplicationMapping.java (with props) Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java tomcat/trunk/java/org/apache/catalina/core/ApplicationMapping.java tomcat/trunk/java/org/apache/catalina/mapper/Mapper.java tomcat/trunk/java/org/apache/catalina/mapper/MappingData.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=1734095&r1=1734094&r2=1734095&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Tue Mar 8 14:12:21 2016 @@ -484,6 +484,7 @@ public class Request implements HttpServ } mappingData.recycle(); + applicationMapping.recycle(); applicationRequest = null; if (Globals.IS_SECURITY_ENABLED || Connector.RECYCLE_FACADES) { @@ -622,6 +623,7 @@ public class Request implements HttpServ * Mapping data. */ protected final MappingData mappingData = new MappingData(); + private final ApplicationMapping applicationMapping = new ApplicationMapping(mappingData); /** * @return mapping data. @@ -2179,7 +2181,7 @@ public class Request implements HttpServ @Override public Mapping getMapping() { - return new ApplicationMapping(mappingData); + return applicationMapping.getMapping(); } 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=1734095&r1=1734094&r2=1734095&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/core/ApplicationMapping.java (original) +++ tomcat/trunk/java/org/apache/catalina/core/ApplicationMapping.java Tue Mar 8 14:12:21 2016 @@ -21,30 +21,81 @@ import javax.servlet.http.MappingMatch; import org.apache.catalina.mapper.MappingData; -public class ApplicationMapping implements Mapping { +public class ApplicationMapping { - private final String matchValue; - private final String pattern; - private final MappingMatch mappingMatch; + private final MappingData mappingData; + + private volatile Mapping mapping = null; public ApplicationMapping(MappingData mappingData) { - matchValue = mappingData.matchValue; - pattern = mappingData.matchPattern; - mappingMatch = mappingData.matchType; + this.mappingData = mappingData; } - @Override - public String getMatchValue() { - return matchValue; + public Mapping getMapping() { + if (mapping == null) { + switch (mappingData.matchType) { + case CONTEXT_ROOT: + mapping = new MappingImpl("", "", mappingData.matchType); + break; + case DEFAULT: + mapping = new MappingImpl("/", "/", mappingData.matchType); + break; + case EXACT: + mapping = new MappingImpl(mappingData.wrapperPath.toString(), + mappingData.wrapperPath.toString(), mappingData.matchType); + break; + case EXTENSION: + String path = mappingData.wrapperPath.toString(); + int extIndex = path.lastIndexOf('.'); + mapping = new MappingImpl(path.substring(0, extIndex), + "*" + path.substring(extIndex), mappingData.matchType); + break; + case PATH: + mapping = new MappingImpl(mappingData.pathInfo.toString(), + mappingData.wrapperPath.toString() + "/*", + mappingData.matchType); + break; + case IMPLICIT: + // Treat IMPLICIT as UNKNOWN since Tomcat doesn't use + // implicit mappings + case UNKNOWN: + mapping = new MappingImpl("", "", mappingData.matchType); + break; + } + } + + return mapping; } - @Override - public String getPattern() { - return pattern; + public void recycle() { + mapping = null; } - @Override - public MappingMatch getMatchType() { - return mappingMatch; + private static class MappingImpl implements Mapping { + + private final String matchValue; + private final String pattern; + private final MappingMatch mappingType; + + public MappingImpl(String matchValue, String pattern, MappingMatch mappingType) { + this.matchValue = matchValue; + this.pattern = pattern; + this.mappingType = mappingType; + } + + @Override + public String getMatchValue() { + return matchValue; + } + + @Override + public String getPattern() { + return pattern; + } + + @Override + public MappingMatch getMatchType() { + return mappingType; + } } } Modified: tomcat/trunk/java/org/apache/catalina/mapper/Mapper.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/mapper/Mapper.java?rev=1734095&r1=1734094&r2=1734095&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/mapper/Mapper.java (original) +++ tomcat/trunk/java/org/apache/catalina/mapper/Mapper.java Tue Mar 8 14:12:21 2016 @@ -25,6 +25,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; +import javax.servlet.http.MappingMatch; + import org.apache.catalina.Context; import org.apache.catalina.Host; import org.apache.catalina.WebResource; @@ -992,6 +994,7 @@ public final class Mapper { (path.getBuffer(), path.getStart(), path.getLength()); mappingData.wrapperPath.setChars (path.getBuffer(), path.getStart(), path.getLength()); + mappingData.matchType = MappingMatch.DEFAULT; } // Redirection to a folder char[] buf = path.getBuffer(); @@ -1040,8 +1043,10 @@ public final class Mapper { mappingData.wrapperPath.setString(""); // This seems wrong but it is what the spec says... mappingData.contextPath.setString(""); + mappingData.matchType = MappingMatch.CONTEXT_ROOT; } else { mappingData.wrapperPath.setString(wrapper.name); + mappingData.matchType = MappingMatch.EXACT; } } } @@ -1093,6 +1098,7 @@ public final class Mapper { (path.getBuffer(), path.getOffset(), path.getLength()); mappingData.wrapper = wrappers[pos].object; mappingData.jspWildCard = wrappers[pos].jspWildCard; + mappingData.matchType = MappingMatch.PATH; } } } @@ -1137,6 +1143,7 @@ public final class Mapper { mappingData.requestPath.setChars(buf, servletPath, pathEnd - servletPath); mappingData.wrapper = wrapper.object; + mappingData.matchType = MappingMatch.EXTENSION; } path.setOffset(servletPath); path.setEnd(pathEnd); Modified: tomcat/trunk/java/org/apache/catalina/mapper/MappingData.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/mapper/MappingData.java?rev=1734095&r1=1734094&r2=1734095&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/mapper/MappingData.java (original) +++ tomcat/trunk/java/org/apache/catalina/mapper/MappingData.java Tue Mar 8 14:12:21 2016 @@ -46,8 +46,6 @@ public class MappingData { public final MessageBytes redirectPath = MessageBytes.newInstance(); // Fields used by ApplicationMapping to implement javax.servlet.http.Mapping - public String matchValue = ""; - public String matchPattern = ""; public MappingMatch matchType = MappingMatch.UNKNOWN; public void recycle() { @@ -62,8 +60,6 @@ public class MappingData { wrapperPath.recycle(); pathInfo.recycle(); redirectPath.recycle(); - matchValue = ""; - matchPattern= ""; matchType = MappingMatch.UNKNOWN; } } Added: 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=1734095&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/catalina/core/TestApplicationMapping.java (added) +++ tomcat/trunk/test/org/apache/catalina/core/TestApplicationMapping.java Tue Mar 8 14:12:21 2016 @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.catalina.core; + +import java.io.IOException; +import java.io.PrintWriter; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.Mapping; + +import org.apache.catalina.Context; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.tomcat.util.buf.ByteChunk; +import org.junit.Assert; +import org.junit.Test; + +public class TestApplicationMapping extends TomcatBaseTest { + + @Test + public void testContextNonRootMappingContextRoot() throws Exception { + doTestMapping("/dummy", "", "", "", "CONTEXT_ROOT"); + } + + @Test + public void testContextNonRootMappingDefault() throws Exception { + doTestMapping("/dummy", "/", "/foo", "/", "DEFAULT"); + } + + @Test + public void testContextNonRootMappingExtension() throws Exception { + doTestMapping("/dummy", "*.test", "/foo/bar.test", "/foo/bar", "EXTENSION"); + } + + @Test + public void testContextNonRootMappingExact() throws Exception { + doTestMapping("/dummy", "/foo/bar", "/foo/bar", "/foo/bar", "EXACT"); + } + + @Test + public void testContextNonRootMappingPath() throws Exception { + doTestMapping("/dummy", "/foo/bar/*", "/foo/bar/foo2", "/foo2", "PATH"); + } + + @Test + public void testContextRootMappingContextRoot() throws Exception { + doTestMapping("", "", "", "", "CONTEXT_ROOT"); + } + + @Test + public void testContextRootMappingDefault() throws Exception { + doTestMapping("", "/", "/foo", "/", "DEFAULT"); + } + + @Test + public void testContextRootMappingExtension() throws Exception { + doTestMapping("", "*.test", "/foo/bar.test", "/foo/bar", "EXTENSION"); + } + + @Test + public void testContextRootMappingExact() throws Exception { + doTestMapping("", "/foo/bar", "/foo/bar", "/foo/bar", "EXACT"); + } + + @Test + public void testContextRootMappingPath() throws Exception { + doTestMapping("", "/foo/bar/*", "/foo/bar/foo2", "/foo2", "PATH"); + } + + private void doTestMapping(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, "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 + "]")); + } + + + private static class MappingServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + resp.setContentType("text/plain;charset=UTF-8"); + PrintWriter pw = resp.getWriter(); + Mapping mapping = req.getMapping(); + pw.println("MatchValue=[" + mapping.getMatchValue() + "]"); + pw.println("Pattern=[" + mapping.getPattern() + "]"); + pw.println("MatchType=[" + mapping.getMatchType() + "]"); + } + } +} Propchange: tomcat/trunk/test/org/apache/catalina/core/TestApplicationMapping.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1734095&r1=1734094&r2=1734095&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Tue Mar 8 14:12:21 2016 @@ -161,6 +161,10 @@ the <code>JNDIRealm</code> once they are no longer required. (fschumacher/markt) </fix> + <add> + Implement the proposed Servlet 4.0 API to provide mapping type + information for the current request. (markt) + </add> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org