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 2012/12/01 21:17:40 UTC

svn commit: r1416047 - in /tomcat/trunk: java/org/apache/tomcat/websocket/ test/org/apache/tomcat/websocket/

Author: markt
Date: Sat Dec  1 20:17:38 2012
New Revision: 1416047

URL: http://svn.apache.org/viewvc?rev=1416047&view=rev
Log:
WebSocket 1.0 implementation part 6 of many
Path parameter processing for POJOs
Clearer differentiation between endpoint path, servlet mapping path and path info

Added:
    tomcat/trunk/java/org/apache/tomcat/websocket/UriTemplate.java   (with props)
    tomcat/trunk/test/org/apache/tomcat/websocket/TestUriTemplate.java   (with props)
Modified:
    tomcat/trunk/java/org/apache/tomcat/websocket/PojoMethodMapping.java
    tomcat/trunk/java/org/apache/tomcat/websocket/ServerContainerImpl.java
    tomcat/trunk/java/org/apache/tomcat/websocket/WsEndpointPojo.java
    tomcat/trunk/java/org/apache/tomcat/websocket/WsServlet.java

Modified: tomcat/trunk/java/org/apache/tomcat/websocket/PojoMethodMapping.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/PojoMethodMapping.java?rev=1416047&r1=1416046&r2=1416047&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/PojoMethodMapping.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/PojoMethodMapping.java Sat Dec  1 20:17:38 2012
@@ -28,7 +28,10 @@ public class PojoMethodMapping {
     private final Method onClose;
     private final Method onError;
 
-    public PojoMethodMapping(Class<?> clazzPojo, String path) {
+    private final UriTemplate template;
+
+    public PojoMethodMapping(Class<?> clazzPojo, String path,
+            String mappingPath) {
         Method open = null;
         Method close = null;
         Method error = null;
@@ -48,13 +51,20 @@ public class PojoMethodMapping {
         this.onOpen = open;
         this.onClose = close;
         this.onError = error;
+
+        if (path.length() > mappingPath.length()) {
+            template =
+                    new UriTemplate(path.substring(mappingPath.length() - 1));
+        } else {
+            template = null;
+        }
     }
 
     public Method getOnOpen() {
         return onOpen;
     }
 
-    public Object[] getOnOpenArgs(String path) {
+    public Object[] getOnOpenArgs(String pathInfo) {
         // TODO Auto-generated method stub
         return null;
     }
@@ -63,7 +73,7 @@ public class PojoMethodMapping {
         return onClose;
     }
 
-    public Object[] getOnCloseArgs(String path) {
+    public Object[] getOnCloseArgs(String pathInfo) {
         // TODO Auto-generated method stub
         return null;
     }
@@ -72,7 +82,7 @@ public class PojoMethodMapping {
         return onError;
     }
 
-    public Object[] getOnErrorArgs(String path) {
+    public Object[] getOnErrorArgs(String pathInfo) {
         // TODO Auto-generated method stub
         return null;
     }

Modified: tomcat/trunk/java/org/apache/tomcat/websocket/ServerContainerImpl.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/ServerContainerImpl.java?rev=1416047&r1=1416046&r2=1416047&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/ServerContainerImpl.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/ServerContainerImpl.java Sat Dec  1 20:17:38 2012
@@ -153,7 +153,7 @@ public class ServerContainerImpl extends
         String mappingPath = Util.getServletMappingPath(path);
 
         pojoMap.put(mappingPath.substring(0, mappingPath.length() - 2), pojo);
-        pojoMethodMap.put(pojo, new PojoMethodMapping(pojo, path));
+        pojoMethodMap.put(pojo, new PojoMethodMapping(pojo, path, mappingPath));
         addWsServletMapping(mappingPath);
     }
 
@@ -170,7 +170,7 @@ public class ServerContainerImpl extends
     }
 
 
-    public Endpoint getEndpoint(String servletPath)
+    public Endpoint getEndpoint(String servletPath, String pathInfo)
             throws InstantiationException, IllegalAccessException {
         Class<? extends Endpoint> clazzEndpoint = endpointMap.get(servletPath);
         if (clazzEndpoint != null) {
@@ -184,7 +184,7 @@ public class ServerContainerImpl extends
             PojoMethodMapping mapping = pojoMethodMap.get(clazzPojo);
             if (mapping != null) {
                 Endpoint ep = new WsEndpointPojo(clazzPojo,
-                        mapping, servletPath);
+                        mapping, servletPath, pathInfo);
                 return ep;
             }
         }

Added: tomcat/trunk/java/org/apache/tomcat/websocket/UriTemplate.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/UriTemplate.java?rev=1416047&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/UriTemplate.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/UriTemplate.java Sat Dec  1 20:17:38 2012
@@ -0,0 +1,84 @@
+/*
+ *  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.tomcat.websocket;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class UriTemplate {
+
+    private final Pattern pattern;
+    private final List<String> names = new ArrayList<>();
+
+    public UriTemplate(String template) {
+        // +10 is just a guess at this point
+        StringBuilder pattern = new StringBuilder(template.length() + 10);
+
+
+        int pos = 0;
+        int end = 0;
+        int start = template.indexOf('{');
+        while (start > -1) {
+            end = template.indexOf('}', start);
+            pattern.append('(');
+            pattern.append(template.substring(pos, start));
+            pattern.append(")?([^/]*)");
+            names.add(template.substring(start + 1, end));
+            pos = end + 1;
+            start = template.indexOf('{', pos);
+        }
+
+        // No more matches, append current position to end
+        if (pos < template.length()) {
+            pattern.append('(');
+            pattern.append(template.substring(pos));
+            pattern.append(")?");
+        }
+
+        this.pattern = Pattern.compile(pattern.toString());
+    }
+
+
+    /**
+     * Extract the path parameters from the provided pathInfo based on the
+     * template with which this UriTemplate was constructed.
+     *
+     * @param pathInfo  The pathInfo from which the path parameters are to be
+     *                  extracted
+     * @return  A map of paramater names to values
+     */
+    public Map<String,String> match(String pathInfo) {
+        Map<String,String> result = new HashMap<>();
+        Matcher m = pattern.matcher(pathInfo);
+        m.matches();
+
+        int group = 2;
+        for (String name : names) {
+            String value = m.group(group);
+            if (value != null && value.length() > 0) {
+                result.put(name, value);
+            }
+            group += 2;
+        }
+
+        return result;
+    }
+}

Propchange: tomcat/trunk/java/org/apache/tomcat/websocket/UriTemplate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsEndpointPojo.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsEndpointPojo.java?rev=1416047&r1=1416046&r2=1416047&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsEndpointPojo.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsEndpointPojo.java Sat Dec  1 20:17:38 2012
@@ -37,10 +37,10 @@ public class WsEndpointPojo extends Endp
     private final Object[] onErrorArgs;
 
     public WsEndpointPojo(Class<?> clazzPojo, PojoMethodMapping methodMapping,
-            String path)
+            String ServletPath, String pathInfo)
             throws InstantiationException, IllegalAccessException {
         this.pojo = clazzPojo.newInstance();
-        this.config = new DefaultServerConfiguration(path) {
+        this.config = new DefaultServerConfiguration(ServletPath) {
 
             @Override
             public boolean checkOrigin(String originHeaderValue) {
@@ -52,21 +52,21 @@ public class WsEndpointPojo extends Endp
         if (onOpen == null) {
             onOpenArgs = null;
         } else {
-            onOpenArgs = methodMapping.getOnOpenArgs(path);
+            onOpenArgs = methodMapping.getOnOpenArgs(pathInfo);
         }
 
         onClose = methodMapping.getOnClose();
         if (onClose == null) {
             onCloseArgs = null;
         } else {
-            onCloseArgs = methodMapping.getOnCloseArgs(path);
+            onCloseArgs = methodMapping.getOnCloseArgs(pathInfo);
         }
 
         onError = methodMapping.getOnError();
         if (onError == null) {
             onErrorArgs = null;
         } else {
-            onErrorArgs = methodMapping.getOnErrorArgs(path);
+            onErrorArgs = methodMapping.getOnErrorArgs(pathInfo);
         }
     }
 

Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsServlet.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsServlet.java?rev=1416047&r1=1416046&r2=1416047&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/websocket/WsServlet.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/websocket/WsServlet.java Sat Dec  1 20:17:38 2012
@@ -90,7 +90,7 @@ public class WsServlet extends HttpServl
         ServerContainerImpl cp = ServerContainerImpl.getServerContainer();
         Endpoint ep = null;
         try {
-             ep = cp.getEndpoint(req.getServletPath());
+             ep = cp.getEndpoint(req.getServletPath(), req.getPathInfo());
         } catch (InstantiationException | IllegalAccessException e) {
             // This will trigger an error response
             throw new ServletException(e);

Added: tomcat/trunk/test/org/apache/tomcat/websocket/TestUriTemplate.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/websocket/TestUriTemplate.java?rev=1416047&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/websocket/TestUriTemplate.java (added)
+++ tomcat/trunk/test/org/apache/tomcat/websocket/TestUriTemplate.java Sat Dec  1 20:17:38 2012
@@ -0,0 +1,84 @@
+/*
+ *  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.tomcat.websocket;
+
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class TestUriTemplate {
+
+    @Test
+    public void testBasic() throws Exception {
+        UriTemplate t = new UriTemplate("/{a}/{b}");
+        Map<String,String> result = t.match("/foo/bar");
+
+        Assert.assertEquals(2, result.size());
+        Assert.assertTrue(result.containsKey("a"));
+        Assert.assertTrue(result.containsKey("b"));
+        Assert.assertEquals("foo", result.get("a"));
+        Assert.assertEquals("bar", result.get("b"));
+    }
+
+
+    @Test
+    public void testOneOfTwo() throws Exception {
+        UriTemplate t = new UriTemplate("/{a}/{b}");
+        Map<String,String> result = t.match("/foo");
+
+        Assert.assertEquals(1, result.size());
+        Assert.assertTrue(result.containsKey("a"));
+        Assert.assertEquals("foo", result.get("a"));
+    }
+
+
+    @Test
+    public void testBasicPrefix() throws Exception {
+        UriTemplate t = new UriTemplate("/x{a}/y{b}");
+        Map<String,String> result = t.match("/xfoo/ybar");
+
+        Assert.assertEquals(2, result.size());
+        Assert.assertTrue(result.containsKey("a"));
+        Assert.assertTrue(result.containsKey("b"));
+        Assert.assertEquals("foo", result.get("a"));
+        Assert.assertEquals("bar", result.get("b"));
+    }
+
+
+    @Test
+    public void testPrefixOneOfTwo() throws Exception {
+        UriTemplate t = new UriTemplate("/x{a}/y{b}");
+        Map<String,String> result = t.match("/xfoo");
+
+        Assert.assertEquals(1, result.size());
+        Assert.assertTrue(result.containsKey("a"));
+        Assert.assertEquals("foo", result.get("a"));
+    }
+
+
+    @Test
+    public void testPrefixTwoOfTwo() throws Exception {
+        UriTemplate t = new UriTemplate("/x{a}/y{b}");
+        Map<String,String> result = t.match("/ybar");
+
+        Assert.assertEquals(1, result.size());
+        Assert.assertTrue(result.containsKey("b"));
+        Assert.assertEquals("bar", result.get("b"));
+    }
+}

Propchange: tomcat/trunk/test/org/apache/tomcat/websocket/TestUriTemplate.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r1416047 - in /tomcat/trunk: java/org/apache/tomcat/websocket/ test/org/apache/tomcat/websocket/

Posted by Konstantin Kolinko <kn...@gmail.com>.
2012/12/2  <ma...@apache.org>:
> Author: markt
> Date: Sat Dec  1 20:17:38 2012
> New Revision: 1416047
>
> URL: http://svn.apache.org/viewvc?rev=1416047&view=rev
> Log:
> WebSocket 1.0 implementation part 6 of many
> Path parameter processing for POJOs
> Clearer differentiation between endpoint path, servlet mapping path and path info
>
> Added:
>     tomcat/trunk/java/org/apache/tomcat/websocket/UriTemplate.java   (with props)
>     tomcat/trunk/test/org/apache/tomcat/websocket/TestUriTemplate.java   (with props)
> Modified:
>     tomcat/trunk/java/org/apache/tomcat/websocket/PojoMethodMapping.java
>     tomcat/trunk/java/org/apache/tomcat/websocket/ServerContainerImpl.java
>     tomcat/trunk/java/org/apache/tomcat/websocket/WsEndpointPojo.java
>     tomcat/trunk/java/org/apache/tomcat/websocket/WsServlet.java
>

> --- tomcat/trunk/java/org/apache/tomcat/websocket/UriTemplate.java (added)
> +++ tomcat/trunk/java/org/apache/tomcat/websocket/UriTemplate.java Sat Dec  1 20:17:38 2012
> @@ -0,0 +1,84 @@
> +package org.apache.tomcat.websocket;
> +
> +import java.util.ArrayList;
> +import java.util.HashMap;
> +import java.util.List;
> +import java.util.Map;
> +import java.util.regex.Matcher;
> +import java.util.regex.Pattern;
> +
> +public class UriTemplate {
> +
> +    private final Pattern pattern;
> +    private final List<String> names = new ArrayList<>();
> +
> +    public UriTemplate(String template) {
> +        // +10 is just a guess at this point
> +        StringBuilder pattern = new StringBuilder(template.length() + 10);
> +
> +
> +        int pos = 0;
> +        int end = 0;
> +        int start = template.indexOf('{');
> +        while (start > -1) {
> +            end = template.indexOf('}', start);
> +            pattern.append('(');
> +            pattern.append(template.substring(pos, start));

When creating a pattern as above, some quoting is needed, e.g. "." -> "\.".

There is method Pattern.quote(), though I never used it when
concatenating several patterns together.

> +            pattern.append(")?([^/]*)");
> +            names.add(template.substring(start + 1, end));
> +            pos = end + 1;
> +            start = template.indexOf('{', pos);
> +        }
> +
> +        // No more matches, append current position to end
> +        if (pos < template.length()) {
> +            pattern.append('(');
> +            pattern.append(template.substring(pos));
> +            pattern.append(")?");
> +        }
> +
> +        this.pattern = Pattern.compile(pattern.toString());
> +    }

Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org