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/11/01 19:35:08 UTC

svn commit: r1404715 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/ systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/ systests/jaxrs/src/tes...

Author: sergeyb
Date: Thu Nov  1 18:35:08 2012
New Revision: 1404715

URL: http://svn.apache.org/viewvc?rev=1404715&view=rev
Log:
[CXF-4552] Support for mapping multiple multipart form-data parts with the same id to collection parameters bound to that id with Mulltipart attachment

Added:
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentFormJsonFiles2
Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java?rev=1404715&r1=1404714&r2=1404715&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java Thu Nov  1 18:35:08 2012
@@ -137,17 +137,10 @@ public class MultipartProvider extends A
         List<Attachment> infos = AttachmentUtils.getAttachments(
                 mc, attachmentDir, attachmentThreshold, attachmentMaxSize);
         
-        if (Collection.class.isAssignableFrom(c) 
+        boolean collectionExpected = Collection.class.isAssignableFrom(c);
+        if (collectionExpected
             && AnnotationUtils.getAnnotation(anns, Multipart.class) == null) {
-            Class<?> actual = getActualType(t, 0);
-            if (Attachment.class.isAssignableFrom(actual)) {
-                return infos;
-            }
-            Collection<Object> objects = new ArrayList<Object>();
-            for (Attachment a : infos) {
-                objects.add(fromAttachment(a, actual, actual, anns));
-            }
-            return objects;
+            return getAttachmentCollection(t, infos, anns);
         }
         if (Map.class.isAssignableFrom(c)) {
             Map<String, Object> map = new LinkedHashMap<String, Object>(infos.size());
@@ -162,10 +155,17 @@ public class MultipartProvider extends A
         }
         
         Multipart id = AnnotationUtils.getAnnotation(anns, Multipart.class);
-        Attachment multipart = AttachmentUtils.getMultipart(c, id, mt, infos);
+        Attachment multipart = AttachmentUtils.getMultipart(id, mt, infos);
         if (multipart != null) {
-            return fromAttachment(multipart, c, t, anns);
-        } else if (id != null && !id.required()) {
+            if (collectionExpected && !mediaTypeSupported(multipart.getContentType())) {
+                List<Attachment> allMultiparts = AttachmentUtils.getAllMultiparts(id, mt, infos);
+                return getAttachmentCollection(t, allMultiparts, anns);
+            } else {
+                return fromAttachment(multipart, c, t, anns);
+            }
+        } 
+        
+        if (id != null && !id.required()) {
             /*
              * If user asked for a null, give them a null. 
              */
@@ -176,6 +176,18 @@ public class MultipartProvider extends A
         
     }
     
+    private Object getAttachmentCollection(Type t, List<Attachment> infos, Annotation[] anns) throws IOException {
+        Class<?> actual = getActualType(t, 0);
+        if (Attachment.class.isAssignableFrom(actual)) {
+            return infos;
+        }
+        Collection<Object> objects = new ArrayList<Object>();
+        for (Attachment a : infos) {
+            objects.add(fromAttachment(a, actual, actual, anns));
+        }
+        return objects;
+    }
+    
     private Class<?> getActualType(Type type, int pos) {
         Class<?> actual = null;
         try {
@@ -195,37 +207,25 @@ public class MultipartProvider extends A
         } else if (Attachment.class.isAssignableFrom(c)) {
             return multipart;
         } else {
-            boolean isCollection = Collection.class.isAssignableFrom(c);
-            boolean isRecursive = false;
             if (mediaTypeSupported(multipart.getContentType())) {
                 mc.put("org.apache.cxf.multipart.embedded", true);
                 mc.put("org.apache.cxf.multipart.embedded.ctype", multipart.getContentType());
                 mc.put("org.apache.cxf.multipart.embedded.input", 
                        multipart.getDataHandler().getInputStream());
                 anns = new Annotation[]{};
-                isRecursive = true;
             }
-            if (isCollection && !isRecursive) {
-                c = convertTypeToClass(t);
-                return Collections.singletonList(fromAttachment(multipart, c, c, anns));
-            } else {
-                MessageBodyReader<T> r = 
-                    mc.getProviders().getMessageBodyReader(c, t, anns, multipart.getContentType());
-                if (r != null) {
-                    InputStream is = multipart.getDataHandler().getInputStream();
-                    is = decodeIfNeeded(multipart, is);
-                    return r.readFrom(c, t, anns, multipart.getContentType(), multipart.getHeaders(), 
-                                      is);
-                }
+            MessageBodyReader<T> r = 
+                mc.getProviders().getMessageBodyReader(c, t, anns, multipart.getContentType());
+            if (r != null) {
+                InputStream is = multipart.getDataHandler().getInputStream();
+                is = decodeIfNeeded(multipart, is);
+                return r.readFrom(c, t, anns, multipart.getContentType(), multipart.getHeaders(), 
+                                  is);
             }
         }
         return null;
     }
     
-    @SuppressWarnings("unchecked")
-    private <T> Class<T> convertTypeToClass(Type t) {
-        return (Class<T>)InjectionUtils.getActualType(t, 0);
-    }
     
     private InputStream decodeIfNeeded(Attachment multipart, InputStream is) {
         String value = multipart.getHeader("Content-Transfer-Encoding");

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java?rev=1404715&r1=1404714&r2=1404715&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java Thu Nov  1 18:35:08 2012
@@ -21,6 +21,7 @@ package org.apache.cxf.jaxrs.utils.multi
 
 import java.io.IOException;
 import java.util.LinkedHashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.ResourceBundle;
@@ -97,8 +98,7 @@ public final class AttachmentUtils {
                                 attachmentMaxSize).getAllAttachments();
     }
     
-    public static Attachment getMultipart(Class<Object> c, 
-                                          Multipart id, 
+    public static Attachment getMultipart(Multipart id, 
                                           MediaType mt, 
                                           List<Attachment> infos) throws IOException {
         
@@ -126,6 +126,20 @@ public final class AttachmentUtils {
         return infos.size() > 0 ? infos.get(0) : null; 
     }
     
+    public static List<Attachment> getAllMultiparts(Multipart id, 
+                                              MediaType mt, 
+                                              List<Attachment> infos) throws IOException {
+    
+        List<Attachment> all = new LinkedList<Attachment>();
+        for (Attachment a : infos) {
+            if (matchAttachmentId(a, id, mt)) {
+                checkMediaTypes(a.getContentType(), id.type());
+                all.add(a);    
+            }
+        }
+        return all;
+    }
+    
     private static boolean matchAttachmentId(Attachment at, Multipart mid, MediaType multipartType) {
         if (at.getContentId().equals(mid.value())) {
             return true;

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=1404715&r1=1404714&r2=1404715&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 Thu Nov  1 18:35:08 2012
@@ -136,6 +136,12 @@ public class JAXRSMultipartTest extends 
     }
     
     @Test
+    public void testBookJSONFormTwoFilesNotRecursive() throws Exception {
+        String address = "http://localhost:" + PORT + "/bookstore/books/filesform";
+        doAddFormBook(address, "attachmentFormJsonFiles2", 200);               
+    }
+    
+    @Test
     public void testBookJSONFormOneFileWhereManyExpected() throws Exception {
         String address = "http://localhost:" + PORT + "/bookstore/books/filesform/singlefile";
         doAddFormBook(address, "attachmentFormJsonFile", 200);               

Added: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentFormJsonFiles2
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentFormJsonFiles2?rev=1404715&view=auto
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentFormJsonFiles2 (added)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/attachmentFormJsonFiles2 Thu Nov  1 18:35:08 2012
@@ -0,0 +1,19 @@
+
+--bqJky99mlBWa-ZuqjC53mG6EzbmlxB
+Content-Disposition: form-data; name="owner"
+Content-Type: text/plain
+
+Larry
+--bqJky99mlBWa-ZuqjC53mG6EzbmlxB
+Content-Disposition: form-data; name="files"; filename="book1.text"
+Content-Type: application/json; charset=US-ASCII
+Content-Transfer-Encoding: 8bit
+
+{"Book":{"name":"CXF in Action - 1","id":123}}
+--bqJky99mlBWa-ZuqjC53mG6EzbmlxB
+Content-Disposition: form-data; name="files";  filename="book2.text"
+Content-Type: application/json; charset=US-ASCII
+Content-Transfer-Encoding: 8bit
+
+{"Book":{"name":"CXF in Action - 2%","id":124}}
+--bqJky99mlBWa-ZuqjC53mG6EzbmlxB--
\ No newline at end of file