You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2012/03/12 15:28:31 UTC

svn commit: r1299682 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/

Author: sergeyb
Date: Mon Mar 12 14:28:31 2012
New Revision: 1299682

URL: http://svn.apache.org/viewvc?rev=1299682&view=rev
Log:
[CXF-4178] Fixing ClientProxyImpl to handle Multipart annotations

Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java?rev=1299682&r1=1299681&r2=1299682&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java Mon Mar 12 14:28:31 2012
@@ -50,12 +50,15 @@ import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.interceptor.InterceptorProvider;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.Multipart;
 import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.jaxrs.model.OperationResourceInfo;
 import org.apache.cxf.jaxrs.model.Parameter;
 import org.apache.cxf.jaxrs.model.ParameterType;
 import org.apache.cxf.jaxrs.provider.ProviderFactory;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
 import org.apache.cxf.jaxrs.utils.FormUtils;
 import org.apache.cxf.jaxrs.utils.InjectionUtils;
 import org.apache.cxf.message.Exchange;
@@ -137,7 +140,7 @@ public class ClientProxyImpl extends Abs
             reportInvalidResourceMethod(m, "INVALID_RESOURCE_METHOD");
         }
         
-        MultivaluedMap<ParameterType, Parameter> types = getParametersInfo(ori);
+        MultivaluedMap<ParameterType, Parameter> types = getParametersInfo(params, ori);
         List<Object> pathParams = getPathParamValues(types, params, ori);
         
         int bodyIndex = getBodyIndex(types, ori);
@@ -183,10 +186,14 @@ public class ClientProxyImpl extends Abs
         getState().setTemplates(getTemplateParametersMap(ori.getURITemplate(), pathParams));
         
         Object body = null;
-        boolean isForm = types.containsKey(ParameterType.FORM);
-        if (bodyIndex != -1 || isForm) {
-            body = isForm ? handleForm(types, params) : params[bodyIndex];
+        if (bodyIndex != -1) {
+            body = params[bodyIndex];
+        } else if (types.containsKey(ParameterType.FORM))  {
+            body = handleForm(types, params);
+        } else if (types.containsKey(ParameterType.REQUEST_BODY))  {
+            body = handleMultipart(types, ori, params);
         }
+        
         return doChainedInvocation(uri, headers, ori, body, bodyIndex, null, null);
         
     }
@@ -197,7 +204,8 @@ public class ClientProxyImpl extends Abs
         }
     }
     
-    private static MultivaluedMap<ParameterType, Parameter> getParametersInfo(OperationResourceInfo ori) {
+    private static MultivaluedMap<ParameterType, Parameter> getParametersInfo(
+        Object[] params, OperationResourceInfo ori) {
         MultivaluedMap<ParameterType, Parameter> map = 
             new MetadataMap<ParameterType, Parameter>();
         
@@ -205,15 +213,24 @@ public class ClientProxyImpl extends Abs
         if (parameters.size() == 0) {
             return map;
         }
+        int requestBodyParam = 0;
+        int multipartParam = 0;
         for (Parameter p : parameters) {
             if (p.getType() == ParameterType.CONTEXT) {
                 // ignore
                 continue;
             }
+            if (p.getType() == ParameterType.REQUEST_BODY) {
+                requestBodyParam++;
+                if (getMultipart(ori, p.getIndex()) != null) {
+                    multipartParam++;    
+                }
+            }
             map.add(p.getType(), p);
         }
+        
         if (map.containsKey(ParameterType.REQUEST_BODY)) {
-            if (map.get(ParameterType.REQUEST_BODY).size() > 1) {
+            if (requestBodyParam > 1 && requestBodyParam != multipartParam) {
                 reportInvalidResourceMethod(ori.getMethodToInvoke(), "SINGLE_BODY_ONLY");
             }
             if (map.containsKey(ParameterType.FORM)) {
@@ -226,7 +243,7 @@ public class ClientProxyImpl extends Abs
     private static int getBodyIndex(MultivaluedMap<ParameterType, Parameter> map, 
                                     OperationResourceInfo ori) {
         List<Parameter> list = map.get(ParameterType.REQUEST_BODY);
-        int index  = list == null ? -1 : list.get(0).getIndex(); 
+        int index = list == null || list.size() > 1 ? -1 : list.get(0).getIndex();
         if (ori.isSubResourceLocator() && index != -1) {
             reportInvalidResourceMethod(ori.getMethodToInvoke(), "NO_BODY_IN_SUBRESOURCE");
         }
@@ -430,6 +447,21 @@ public class ClientProxyImpl extends Abs
         return form;
     }
     
+    private List<Attachment> handleMultipart(MultivaluedMap<ParameterType, Parameter> map,
+                                             OperationResourceInfo ori,
+                                             Object[] params) {
+        
+        List<Attachment> atts = new LinkedList<Attachment>();
+        List<Parameter> fm = getParameters(map, ParameterType.REQUEST_BODY);
+        for (Parameter p : fm) {
+            Multipart part = getMultipart(ori, p.getIndex());
+            if (part != null) {
+                atts.add(new Attachment(part.value(), part.type(), params[p.getIndex()]));
+            }
+        }
+        return atts;        
+    }
+    
     private void handleHeaders(MultivaluedMap<String, String> headers,
                                MultivaluedMap<ParameterType, Parameter> map, Object[] params) {
         List<Parameter> hs = getParameters(map, ParameterType.HEADER);
@@ -440,6 +472,12 @@ public class ClientProxyImpl extends Abs
         }
     }
     
+    private static Multipart getMultipart(OperationResourceInfo ori, int index) {
+        Method aMethod = ori.getAnnotatedMethod();
+        return aMethod != null ? AnnotationUtils.getAnnotation(
+            aMethod.getParameterAnnotations()[index], Multipart.class) : null;
+    }
+    
     private void handleCookies(MultivaluedMap<String, String> headers,
                                MultivaluedMap<ParameterType, Parameter> map, Object[] params) {
         List<Parameter> cs = getParameters(map, ParameterType.COOKIE);

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java?rev=1299682&r1=1299681&r2=1299682&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java Mon Mar 12 14:28:31 2012
@@ -231,6 +231,27 @@ public class JAXRSMultipartTest extends 
     }
     
     @Test
+    public void testAddBookAsJAXBJSONProxy() throws Exception {
+        MultipartStore store = 
+            JAXRSClientFactory.create("http://localhost:" + PORT, MultipartStore.class);
+        
+        Book b = store.addBookJaxbJsonWithConsumes(new Book2("CXF in Action", 1L), 
+                                           new Book("CXF in Action - 2", 2L));
+        assertEquals(124L, b.getId());
+        assertEquals("CXF in Action - 2", b.getName());
+    }
+    
+    @Test
+    public void testAddBookAsJAXBOnlyProxy() throws Exception {
+        MultipartStore store = 
+            JAXRSClientFactory.create("http://localhost:" + PORT, MultipartStore.class);
+        
+        Book2 b = store.addBookJaxbOnlyWithConsumes(new Book2("CXF in Action", 1L));
+        assertEquals(1L, b.getId());
+        assertEquals("CXF in Action", b.getName());
+    }
+    
+    @Test
     public void testAddBookAsJAXBJSONMixed() throws Exception {
         String address = "http://localhost:" + PORT + "/bookstore/books/jaxbjson";
         doAddBook("multipart/mixed", address, "attachmentData2", 200);               

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java?rev=1299682&r1=1299681&r2=1299682&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java Mon Mar 12 14:28:31 2012
@@ -353,9 +353,31 @@ public class MultipartStore {
     }
     
     @POST
+    @Path("/books/jaxbjsonconsumes")
+    @Consumes("multipart/related")
+    @Produces("text/xml")
+    public Book addBookJaxbJsonWithConsumes(
+        @Multipart(value = "rootPart", type = "text/xml") Book2 b1,
+        @Multipart(value = "book2", type = "application/json") Book b2) throws Exception {
+        return addBookJaxbJson(b1, b2);    
+    }
+    
+    @POST
+    @Path("/books/jaxbonly")
+    @Consumes("multipart/related")
+    @Produces("text/xml")
+    public Book2 addBookJaxbOnlyWithConsumes(
+        @Multipart(value = "rootPart", type = "text/xml") Book2 b1) throws Exception {
+        if (!"CXF in Action".equals(b1.getName())) {
+            throw new WebApplicationException();
+        }
+        return b1;    
+    }
+    
+    @POST
     @Path("/books/jaxbjson")
     @Produces("text/xml")
-    public Response addBookJaxbJson(
+    public Book addBookJaxbJson(
         @Multipart(value = "rootPart", type = "text/xml") Book2 b1,
         @Multipart(value = "book2", type = "application/json") Book b2) 
         throws Exception {
@@ -364,7 +386,7 @@ public class MultipartStore {
             throw new WebApplicationException();
         }
         b2.setId(124);
-        return Response.ok(b2).build();
+        return b2;
     }
     
     @POST