You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2016/03/08 15:12:21 UTC

svn commit: r1734095 - in /tomcat/trunk: java/org/apache/catalina/connector/ java/org/apache/catalina/core/ java/org/apache/catalina/mapper/ test/org/apache/catalina/core/ webapps/docs/

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org