You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wink.apache.org by bl...@apache.org on 2010/09/15 23:59:50 UTC

svn commit: r997523 - in /incubator/wink/trunk/wink-server/src: main/java/org/apache/wink/server/internal/registry/ test/java/org/apache/wink/server/internal/registry/ test/java/org/apache/wink/server/utils/

Author: bluk
Date: Wed Sep 15 21:59:50 2010
New Revision: 997523

URL: http://svn.apache.org/viewvc?rev=997523&view=rev
Log:
Fix issue with PathParam not resolving last value

Thanks to Kaloyan Kolev for reporting the issue with test.

Thanks to Mike Rheinheimer for helping fix this issue.

See [WINK-311]

Added:
    incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/utils/SubResourceSamePathParamSegmentTest.java
    incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/utils/SubresourceSamePathParamTest.java
Modified:
    incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java
    incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/InjectableDataTest.java
    incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/ValueConvertorTest.java

Modified: incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java?rev=997523&r1=997522&r2=997523&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java (original)
+++ incubator/wink/trunk/wink-server/src/main/java/org/apache/wink/server/internal/registry/ServerInjectableFactory.java Wed Sep 15 21:59:50 2010
@@ -428,7 +428,11 @@ public class ServerInjectableFactory ext
             MultivaluedMap<String, List<PathSegment>> pathSegmentsMap =
                 runtimeContext.getAttribute(SearchResult.class).getData()
                     .getMatchedVariablesPathSegments();
-            List<PathSegment> segments = pathSegmentsMap.getFirst(getName());
+            List<PathSegment> segments = null;
+            List<List<PathSegment>> listOfListPathSegments = pathSegmentsMap.get(getName());
+            if (listOfListPathSegments != null && listOfListPathSegments.size() > 0) {
+                segments = listOfListPathSegments.get(listOfListPathSegments.size() - 1);
+            }
             if (segments != null && segments.size() > 0) {
                 // special handling for PathSegment
                 if (isTypeOf(PathSegment.class)) {
@@ -478,12 +482,24 @@ public class ServerInjectableFactory ext
                 } else {
                     values.add(defaultValue);
                 }
+                decodeValues(values);
+                try {
+                    return getConvertor().convert(values);
+                } catch (ConversionException e) {
+                    throw new WebApplicationException(e.getCause(), Response.Status.NOT_FOUND);
+                }
             }
 
             decodeValues(values);
 
             try {
-                return getConvertor().convert(values);
+                // does not make sense to support List as a PathParam method
+                // parameter, so, we get the last value:
+                if (values.size() > 0) {
+                    return getConvertor().convert(values.get(values.size() - 1));
+                } else {
+                    return getConvertor().convert(values);
+                }
             } catch (ConversionException e) {
                 throw new WebApplicationException(e.getCause(), Response.Status.NOT_FOUND);
             }

Modified: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/InjectableDataTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/InjectableDataTest.java?rev=997523&r1=997522&r2=997523&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/InjectableDataTest.java (original)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/InjectableDataTest.java Wed Sep 15 21:59:50 2010
@@ -100,9 +100,8 @@ public class InjectableDataTest extends 
         @Path("simpleListMulti/{p:.*/.*}")
         @Produces
         public void getSimpleListMulti(@PathParam("p") List<String> p) {
-            assertEquals(2, p.size());
-            assertEquals("a b+c", p.get(0));
-            assertEquals("a/b", p.get(1));
+            assertEquals(1, p.size());
+            assertEquals("a/b", p.get(0));
         }
 
         @GET

Modified: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/ValueConvertorTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/ValueConvertorTest.java?rev=997523&r1=997522&r2=997523&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/ValueConvertorTest.java (original)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/ValueConvertorTest.java Wed Sep 15 21:59:50 2010
@@ -404,14 +404,15 @@ public class ValueConvertorTest extends 
             assertEquals(null, p);
         }
 
-        // List
+        // List:  NOTE: very strange to support PathParam as a list, but if people
+        // really want it, they have it.  See JavaDoc for PathParam; there is no statement
+        // about supporting PathParam as a list.  All other *Param are support as list.
 
         @GET
         @Path("ListInteger/{p}")
         @Produces
         public void getListInteger(@PathParam("p") List<Integer> p) {
             List<Integer> list = new ArrayList<Integer>();
-            list.add(1);
             list.add(2);
             assertEquals(list, p);
         }
@@ -428,7 +429,6 @@ public class ValueConvertorTest extends 
         @Produces
         public void getListString(@PathParam("p") List<String> p) {
             List<String> list = new ArrayList<String>();
-            list.add("1");
             list.add("2");
             assertEquals(list, p);
         }
@@ -445,7 +445,6 @@ public class ValueConvertorTest extends 
         @Produces
         public void getListStringConstructor(@PathParam("p") List<StringConstructorClass> p) {
             List<StringConstructorClass> list = new ArrayList<StringConstructorClass>();
-            list.add(new StringConstructorClass("1"));
             list.add(new StringConstructorClass("2"));
             assertEquals(list, p);
         }
@@ -462,7 +461,6 @@ public class ValueConvertorTest extends 
         @Produces
         public void getListValueOf(@PathParam("p") List<ValueOfClass> p) {
             List<ValueOfClass> list = new ArrayList<ValueOfClass>();
-            list.add(ValueOfClass.valueOf("1"));
             list.add(ValueOfClass.valueOf("2"));
             assertEquals(list, p);
         }
@@ -481,7 +479,6 @@ public class ValueConvertorTest extends 
         @Produces
         public void getSetInteger(@PathParam("p") Set<Integer> p) {
             Set<Integer> list = new HashSet<Integer>();
-            list.add(1);
             list.add(2);
             assertEquals(list, p);
         }
@@ -498,7 +495,6 @@ public class ValueConvertorTest extends 
         @Produces
         public void getSetString(@PathParam("p") Set<String> p) {
             Set<String> list = new HashSet<String>();
-            list.add("1");
             list.add("2");
             assertEquals(list, p);
         }
@@ -515,7 +511,6 @@ public class ValueConvertorTest extends 
         @Produces
         public void getSetStringConstructor(@PathParam("p") Set<StringConstructorClass> p) {
             Set<StringConstructorClass> list = new HashSet<StringConstructorClass>();
-            list.add(new StringConstructorClass("1"));
             list.add(new StringConstructorClass("2"));
             assertEquals(list, p);
         }
@@ -532,7 +527,6 @@ public class ValueConvertorTest extends 
         @Produces
         public void getSetValueOf(@PathParam("p") Set<ValueOfClass> p) {
             Set<ValueOfClass> list = new HashSet<ValueOfClass>();
-            list.add(ValueOfClass.valueOf("1"));
             list.add(ValueOfClass.valueOf("2"));
             assertEquals(list, p);
         }
@@ -551,7 +545,6 @@ public class ValueConvertorTest extends 
         @Produces
         public void getSortedSetInteger(@PathParam("p") SortedSet<Integer> p) {
             SortedSet<Integer> list = new TreeSet<Integer>();
-            list.add(1);
             list.add(2);
             assertEquals(list, p);
         }
@@ -568,7 +561,6 @@ public class ValueConvertorTest extends 
         @Produces
         public void getSortedSetString(@PathParam("p") SortedSet<String> p) {
             SortedSet<String> list = new TreeSet<String>();
-            list.add("1");
             list.add("2");
             assertEquals(list, p);
         }
@@ -585,7 +577,6 @@ public class ValueConvertorTest extends 
         @Produces
         public void getSortedSetStringConstructor(@PathParam("p") SortedSet<StringConstructorClass> p) {
             SortedSet<StringConstructorClass> list = new TreeSet<StringConstructorClass>();
-            list.add(new StringConstructorClass("1"));
             list.add(new StringConstructorClass("2"));
             assertEquals(list, p);
         }
@@ -602,7 +593,6 @@ public class ValueConvertorTest extends 
         @Produces
         public void getSortedSetValueOf(@PathParam("p") SortedSet<ValueOfClass> p) {
             SortedSet<ValueOfClass> list = new TreeSet<ValueOfClass>();
-            list.add(ValueOfClass.valueOf("1"));
             list.add(ValueOfClass.valueOf("2"));
             assertEquals(list, p);
         }

Added: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/utils/SubResourceSamePathParamSegmentTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/utils/SubResourceSamePathParamSegmentTest.java?rev=997523&view=auto
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/utils/SubResourceSamePathParamSegmentTest.java (added)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/utils/SubResourceSamePathParamSegmentTest.java Wed Sep 15 21:59:50 2010
@@ -0,0 +1,81 @@
+/*
+ * 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.wink.server.utils;
+
+import java.util.List;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.PathSegment;
+
+import org.apache.wink.server.internal.servlet.MockServletInvocationTest;
+import org.apache.wink.test.mock.MockRequestConstructor;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+public class SubResourceSamePathParamSegmentTest extends MockServletInvocationTest {
+
+    @Override
+    protected Class<?>[] getClasses() {
+        Class<?>[] classes = new Class<?>[] {TopResource.class};
+        return classes;
+    }
+
+    @Path("/top")
+    public static class TopResource {
+        @Path("{id}")
+        public MidResource getByid(@PathParam("id") PathSegment id) {
+            if ("1".equals(id.getPath())) {
+                return new MidResource();
+            }
+            return null;
+        }
+    }
+
+    public static class MidResource {
+        @Path("{id}")
+        // same name as in TopResource
+        public BottomResource getByid(@PathParam("id") List<PathSegment> id) {
+            if ("2".equals(id.get(0).getPath())) { // different number than the
+                                                   // conditional in
+                // TopResource.getByid
+                return new BottomResource();
+            }
+            return null;
+        }
+    }
+
+    public static class BottomResource {
+        @GET
+        public String get() {
+            return "you found me";
+        }
+    }
+
+    public void testMultiSubresources() throws Exception {
+        MockHttpServletRequest request =
+            MockRequestConstructor.constructMockRequest("GET", "/top/1/2", MediaType.TEXT_PLAIN);
+        MockHttpServletResponse response = invoke(request);
+        assertEquals(200, response.getStatus());
+        assertEquals("you found me", response.getContentAsString());
+    }
+
+}

Added: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/utils/SubresourceSamePathParamTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/utils/SubresourceSamePathParamTest.java?rev=997523&view=auto
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/utils/SubresourceSamePathParamTest.java (added)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/utils/SubresourceSamePathParamTest.java Wed Sep 15 21:59:50 2010
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * 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.wink.server.utils;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.wink.server.internal.servlet.MockServletInvocationTest;
+import org.apache.wink.test.mock.MockRequestConstructor;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+/*
+ * test what happens when deeply nested subresources
+ * use the same path param identifier in the @Path annotation
+ */
+public class SubresourceSamePathParamTest extends MockServletInvocationTest {
+
+    @Override
+    protected Class<?>[] getClasses() {
+        Class<?>[] classes = new Class<?>[]{TopResource.class};
+        return classes;
+    }
+    
+    @Path("/top")
+    public static class TopResource {
+        @Path("{id}")
+        public MidResource getByid(@PathParam("id") int id) {
+            if (id == 1) {
+                return new MidResource();
+            }
+            return null;
+        }
+    }
+    
+    public static class MidResource {
+        @Path("{id}")  // same name as in TopResource
+        public BottomResource getByid(@PathParam("id") int id) {
+            if (id == 2) {  // different number than the conditional in TopResource.getByid
+                return new BottomResource();
+            }
+            return null;
+        }
+    }
+    
+    public static class BottomResource {
+        @GET
+        public String get() {
+            return "you found me";
+        }
+    }
+    
+    public void testMultiSubresources() throws Exception {
+        MockHttpServletRequest request =
+            MockRequestConstructor.constructMockRequest("GET",
+                                                        "/top/1/2",
+                                                        MediaType.TEXT_PLAIN);
+        MockHttpServletResponse response = invoke(request);
+        assertEquals(200, response.getStatus());
+        assertEquals("you found me", response.getContentAsString());
+    }
+    
+}