Author: sergeyb Date: Mon Mar 12 16:46:30 2012 New Revision: 1299737 URL: http://svn.apache.org/viewvc?rev=1299737&view=rev Log: Merged revisions 1299725 via svnmerge from https://svn.apache.org/repos/asf/cxf/branches/2.5.x-fixes
................ r1299725 | sergeyb | 2012-03-12 16:04:13 +0000 (Mon, 12 Mar 2012) | 9 lines Merged revisions 1299682 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk ........ r1299682 | sergeyb | 2012-03-12 14:28:31 +0000 (Mon, 12 Mar 2012) | 1 line [CXF-4178] Fixing ClientProxyImpl to handle Multipart annotations ........ ................ Modified: cxf/branches/2.4.x-fixes/ (props changed) cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java Propchange: cxf/branches/2.4.x-fixes/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Mon Mar 12 16:46:30 2012 @@ -1,2 +1,2 @@ -/cxf/branches/2.5.x-fixes:1299092,1299637 -/cxf/trunk:1298830,1299635 +/cxf/branches/2.5.x-fixes:1299092,1299637,1299725 +/cxf/trunk:1298830,1299635,1299682 Propchange: cxf/branches/2.4.x-fixes/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java?rev=1299737&r1=1299736&r2=1299737&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java Mon Mar 12 16:46:30 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/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java?rev=1299737&r1=1299736&r2=1299737&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java (original) +++ cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java Mon Mar 12 16:46:30 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/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java?rev=1299737&r1=1299736&r2=1299737&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java (original) +++ cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java Mon Mar 12 16:46:30 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
