cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r739366 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ rt/frontend/jaxrs/src/main/...
Date Fri, 30 Jan 2009 18:23:53 GMT
Author: sergeyb
Date: Fri Jan 30 18:23:52 2009
New Revision: 739366

URL: http://svn.apache.org/viewvc?rev=739366&view=rev
Log:
JAXRS: support for multipart/form-data

Added:
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentForm
Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentInputInterceptor.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProvider.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBodyTest.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProviderTest.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
Fri Jan 30 18:23:52 2009
@@ -36,7 +36,7 @@
 public interface MessageContext {
     
     Object get(Object key);
-    void put(Object key, Object value);
+    void put(Object key, Object value, boolean outbound);
     
     UriInfo getUriInfo();
     Request getRequest();

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
Fri Jan 30 18:23:52 2009
@@ -112,8 +112,12 @@
         return JAXRSUtils.createServletResourceValue(m, ServletContext.class);
     }
 
-    public void put(Object key, Object value) {
-        throw new UnsupportedOperationException("MessageContext.put() is not supported yet");
+    public void put(Object key, Object value, boolean outbound) {
+        if (outbound) {
+            throw new UnsupportedOperationException(
+                      "MessageContext.put() is not supported for outbound properties");
+        }
+        m.put(key.toString(), value);
     }
 
     private MultipartBody createAttachments(String propertyName) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java
Fri Jan 30 18:23:52 2009
@@ -61,7 +61,8 @@
     }
     
     public ContentDisposition getContentDisposition() {
-        String header = headers.getFirst("Content-Disposition");
+        String header = getHeader("Content-Disposition");
+        
         return header == null ? null : new ContentDisposition(header);
     }
 
@@ -79,11 +80,13 @@
     }
 
     public String getHeader(String name) {
-        return headers.getFirst(name);
+        String header = headers.getFirst(name);
+        return header == null ? headers.getFirst(name.toLowerCase()) : header; 
     }
     
     public List<String> getHeaderAsList(String name) {
-        return headers.get(name);
+        List<String> header = headers.get(name);
+        return header == null ? headers.get(name.toLowerCase()) : header;
     }
 
     public MultivaluedMap<String, String> getHeaders() {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java
Fri Jan 30 18:23:52 2009
@@ -73,5 +73,12 @@
         return atts.size() > 0 ? atts.get(0) : null;
     }
     
-    
+    public Attachment getAttachment(String contentId) {
+        for (Attachment a : atts) {
+            if (contentId.equalsIgnoreCase(a.getContentId())) {
+                return a;
+            }
+        }
+        return null;
+    }
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
Fri Jan 30 18:23:52 2009
@@ -78,9 +78,9 @@
         return get() != null ? get().getRequest() : null;
     }
 
-    public void put(Object key, Object value) {
+    public void put(Object key, Object value, boolean outbound) {
         if (get() != null) {
-            get().put(key, value);
+            get().put(key, value, outbound);
         }
         throw new IllegalStateException("MessageContext is not set");
         

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentInputInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentInputInterceptor.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentInputInterceptor.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentInputInterceptor.java
Fri Jan 30 18:23:52 2009
@@ -29,7 +29,10 @@
 public class AttachmentInputInterceptor extends AttachmentInInterceptor {
     
     private static final List<String> DEFAULT_TYPES = 
-        Arrays.asList(new String[]{"multipart/related", "multipart/mixed"});
+        Arrays.asList(new String[]{"multipart/related", 
+                                   "multipart/mixed",
+                                   "multipart/alternative",
+                                   "multipart/form-data"});
     
     private List<String> types = DEFAULT_TYPES;
     

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
Fri Jan 30 18:23:52 2009
@@ -38,23 +38,32 @@
 
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
 import org.apache.cxf.jaxrs.utils.InjectionUtils;
 import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
 
 @Provider
-@Consumes({"multipart/related", "multipart/mixed" })
+@Consumes({"multipart/related", "multipart/mixed", "multipart/alternative" })
 public class ActivationProvider implements MessageBodyReader<Object> {
 
     @Context
     private MessageContext mc;
+    private String attachmentDir;
+    private String attachmentThreshold;
+
+    public void setAttachmentDirectory(String dir) {
+        attachmentDir = dir;
+    }
+    
+    public void setAttachmentThreshold(String threshold) {
+        attachmentThreshold = threshold;
+    }
     
     public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations,

                               MediaType mt) {
-        if (DataHandler.class.isAssignableFrom(type) 
-            || DataSource.class.isAssignableFrom(type)
-            || Attachment.class.isAssignableFrom(type)
-            || (mt.getType().equals("multipart") 
-                && (mt.getSubtype().equals("related") || mt.getSubtype().equals("mixed"))))
{
+        if (DataHandler.class.isAssignableFrom(type) || DataSource.class.isAssignableFrom(type)
+            || Attachment.class.isAssignableFrom(type) || MultipartBody.class.isAssignableFrom(type)
+            || mediaTypeSupported(mt)) {
             return true;
         }
         return false;
@@ -64,9 +73,11 @@
                            MultivaluedMap<String, String> headers, InputStream is)

         throws IOException, WebApplicationException {
         
+        List<Attachment> infos = 
+            AttachmentUtils.getAttachments(mc, attachmentDir, attachmentThreshold);
+        
         if (List.class.isAssignableFrom(c)) {
             Class<?> actual = InjectionUtils.getActualType(t);
-            List<Attachment> infos = AttachmentUtils.getAttachments(mc);
             if (actual.isAssignableFrom(Attachment.class)) {
                 return infos;
             }
@@ -76,8 +87,11 @@
             }
             return objects;
         }
+        if (MultipartBody.class.isAssignableFrom(c)) {
+            return new MultipartBody(infos);
+        }
         
-        Attachment multipart = AttachmentUtils.getMultipart(c, anns, mt, mc);
+        Attachment multipart = AttachmentUtils.getMultipart(c, anns, mt, infos);
         if (multipart != null) {
             return fromAttachment(multipart, c, t, anns);
         }
@@ -103,4 +117,9 @@
         }
         return null;
     }
+    
+    private boolean mediaTypeSupported(MediaType mt) {
+        return mt.getType().equals("multipart") && (mt.getSubtype().equals("related")

+            || mt.getSubtype().equals("mixed") || mt.getSubtype().equals("alternative"));
+    }
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProvider.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProvider.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProvider.java
Fri Jan 30 18:23:52 2009
@@ -27,20 +27,35 @@
 import javax.ws.rs.Consumes;
 import javax.ws.rs.Encoded;
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.Provider;
 
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
 import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.utils.AnnotationUtils;
 import org.apache.cxf.jaxrs.utils.FormUtils;
+import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
 
-@Consumes("application/x-www-form-urlencoded")
+@Consumes({"application/x-www-form-urlencoded", "multipart/form-data" })
 @Provider
 public class FormEncodingReaderProvider implements MessageBodyReader<Object> {
-
+        
     private FormValidator validator;
+    @Context private MessageContext mc;
+    private String attachmentDir;
+    private String attachmentThreshold;
+
+    public void setAttachmentDirectory(String dir) {
+        attachmentDir = dir;
+    }
+    
+    public void setAttachmentThreshold(String threshold) {
+        attachmentThreshold = threshold;
+    }
     
     public void setValidator(FormValidator formValidator) {
         validator = formValidator;
@@ -48,17 +63,23 @@
     
     public boolean isReadable(Class<?> type, Type genericType, 
                               Annotation[] annotations, MediaType mt) {
-        return MultivaluedMap.class.isAssignableFrom(type);
+        return MultivaluedMap.class.isAssignableFrom(type)
+               || mt.isCompatible(MediaType.MULTIPART_FORM_DATA_TYPE)
+                  && MultipartBody.class.isAssignableFrom(type);
     }
 
-    public MultivaluedMap<String, String> readFrom(
+    public Object readFrom(
         Class<Object> clazz, Type genericType, Annotation[] annotations, MediaType
type, 
         MultivaluedMap<String, String> headers, InputStream is) 
         throws IOException {
         try {
-
+           
+            if (MultipartBody.class.isAssignableFrom(clazz)) {
+                return AttachmentUtils.getMultipartBody(mc);
+            }
+            
             MultivaluedMap<String, String> params = createMap(clazz);
-            populateMap(params, is, 
+            populateMap(params, is, type,
                         AnnotationUtils.getAnnotation(annotations, Encoded.class) == null);
             validateMap(params);
             return params;
@@ -84,9 +105,14 @@
      * @return a Map of parameters.
      */
     protected void populateMap(MultivaluedMap<String, String> params, 
-                               InputStream is,
-                               boolean decode) {
-        FormUtils.populateMap(params, FormUtils.readBody(is), decode);
+                               InputStream is, MediaType mt, boolean decode) {
+        if (mt.isCompatible(MediaType.MULTIPART_FORM_DATA_TYPE)) {
+            MultipartBody body = 
+                AttachmentUtils.getMultipartBody(mc, attachmentDir, attachmentThreshold);
+            FormUtils.populateMapFromMultipart(params, body, decode);
+        } else {
+            FormUtils.populateMapFromString(params, FormUtils.readBody(is), decode);
+        }
     }
     
     protected void validateMap(MultivaluedMap<String, String> params) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java Fri
Jan 30 18:23:52 2009
@@ -20,6 +20,7 @@
 package org.apache.cxf.jaxrs.utils;
 
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.List;
@@ -29,9 +30,14 @@
 
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
 
 public final class FormUtils {
     
+    private static final String FORM_DATA_TYPE = "form-data";  
+        
     private FormUtils() {
         
     }
@@ -46,8 +52,8 @@
         }
     }
     
-    public static void populateMap(MultivaluedMap<String, String> params, 
-                                   String postBody, boolean decode) {
+    public static void populateMapFromString(MultivaluedMap<String, String> params,

+                                             String postBody, boolean decode) {
         if (!StringUtils.isEmpty(postBody)) {
             List<String> parts = Arrays.asList(postBody.split("&"));
             for (String part : parts) {
@@ -66,4 +72,24 @@
             }
         }
     }
+    
+    public static void populateMapFromMultipart(MultivaluedMap<String, String> params,
+                                                MultipartBody body, 
+                                                boolean decode) {
+        List<Attachment> atts = body.getAllAttachments();
+        for (Attachment a : atts) {
+            ContentDisposition cd = a.getContentDisposition();
+            if (cd == null || !FORM_DATA_TYPE.equalsIgnoreCase(cd.getType())
+                || cd.getParameter("name") == null) {
+                throw new WebApplicationException(415);
+            }
+            String name = cd.getParameter("name").replace("\"", "").replace("'", "");
+            try {
+                String value = IOUtils.toString(a.getDataHandler().getInputStream());
+                params.add(name, decode ? JAXRSUtils.uriDecode(value) : value);
+            } catch (IOException ex) {
+                throw new WebApplicationException(415);
+            }
+        }
+    }
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
Fri Jan 30 18:23:52 2009
@@ -132,6 +132,18 @@
         return (Class<?>)paramType.getActualTypeArguments()[0];
     }
     
+    public static Class<?> getActualType(Type genericType, int i) {
+        if (genericType == null 
+            || !ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
+            return null;
+        }
+        ParameterizedType paramType = (ParameterizedType)genericType;
+        if (i < paramType.getActualTypeArguments().length) {
+            return (Class<?>)paramType.getActualTypeArguments()[i];
+        }
+        return null;
+    }
+    
     public static void injectThroughMethod(Object requestObject,
                                            Method method,
                                            Object parameterValue) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Fri
Jan 30 18:23:52 2009
@@ -76,6 +76,7 @@
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.ext.MessageContextImpl;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
 import org.apache.cxf.jaxrs.impl.HttpHeadersImpl;
 import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.impl.PathSegmentImpl;
@@ -90,6 +91,7 @@
 import org.apache.cxf.jaxrs.model.URITemplate;
 import org.apache.cxf.jaxrs.provider.AbstractConfigurableProvider;
 import org.apache.cxf.jaxrs.provider.ProviderFactory;
+import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.transport.http.AbstractHTTPDestination;
 
@@ -531,14 +533,23 @@
                                            Class<?> pClass, Type genericType,
                                            String defaultValue,
                                            boolean decode) {
+        
+        MessageContext mc = new MessageContextImpl(m);
+        MediaType mt = mc.getHttpHeaders().getMediaType();
+        
         MultivaluedMap<String, String> params = new MetadataMap<String, String>();
-        String body = (String)m.get("org.apache.cxf.jaxrs.provider.form.body");
-        if (body == null) {
-            body = FormUtils.readBody(m.getContent(InputStream.class));
-            m.put("org.apache.cxf.jaxrs.provider.form.body", body);
+        
+        if (mt == null || mt.isCompatible(MediaType.APPLICATION_FORM_URLENCODED_TYPE)) {
+            String body = (String)m.get("org.apache.cxf.jaxrs.provider.form.body");
+            if (body == null) {
+                body = FormUtils.readBody(m.getContent(InputStream.class));
+                m.put("org.apache.cxf.jaxrs.provider.form.body", body);
+            }
+            FormUtils.populateMapFromString(params, (String)body, decode);
+        } else {
+            MultipartBody body = AttachmentUtils.getMultipartBody(mc);
+            FormUtils.populateMapFromMultipart(params, body, decode);
         }
-        // TODO : this is done per every form parameter hence it needs to be refactored
-        FormUtils.populateMap(params, body, decode);
         
         String basePath = HttpUtils.getOriginalAddress(m);
         if ("".equals(key)) {

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=739366&r1=739365&r2=739366&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
Fri Jan 30 18:23:52 2009
@@ -29,14 +29,18 @@
 
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
 
+import org.apache.cxf.attachment.AttachmentDeserializer;
 import org.apache.cxf.common.i18n.BundleUtils;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.ext.multipart.Attachment;
 import org.apache.cxf.jaxrs.ext.multipart.Multipart;
 import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.utils.AnnotationUtils;
+import org.apache.cxf.jaxrs.utils.FormUtils;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
 
 public final class AttachmentUtils {
@@ -46,6 +50,10 @@
     private AttachmentUtils() {
     }
     
+    public static MultipartBody getMultipartBody(MessageContext mc) {
+        return (MultipartBody)mc.get(MultipartBody.INBOUND_MESSAGE_ATTACHMENTS);
+    }
+    
     public static Map<String, Attachment> getChildAttachmentsMap(MessageContext mc)
{
         return fromListToMap(getChildAttachments(mc));
     }
@@ -62,12 +70,27 @@
         return ((MultipartBody)mc.get(MultipartBody.INBOUND_MESSAGE_ATTACHMENTS)).getAllAttachments();
     }
     
+    public static MultipartBody getMultipartBody(MessageContext mc,
+        String attachmentDir, String attachmentThreshold) {
+        if (attachmentDir != null) {
+            mc.put(AttachmentDeserializer.ATTACHMENT_DIRECTORY, attachmentDir, false);
+        }
+        if (attachmentThreshold != null) {
+            mc.put(AttachmentDeserializer.ATTACHMENT_MEMORY_THRESHOLD, attachmentThreshold,
false);
+        }
+        return (MultipartBody)mc.get(MultipartBody.INBOUND_MESSAGE_ATTACHMENTS);
+    }
+    
+    public static List<Attachment> getAttachments(MessageContext mc, 
+        String attachmentDir, String attachmentThreshold) {
+        return getMultipartBody(mc, attachmentDir, attachmentThreshold).getAllAttachments();
+    }
+    
     public static Attachment getMultipart(Class<Object> c, Annotation[] anns, 
-        MediaType mt, MessageContext mc) throws IOException {
-        List<Attachment> infos = AttachmentUtils.getAttachments(mc);
+        MediaType mt, List<Attachment> infos) throws IOException {
         Multipart id = AnnotationUtils.getAnnotation(anns, Multipart.class);
         if (id != null) {
-            for (Attachment a : getAttachments(mc)) {
+            for (Attachment a : infos) {
                 if (a.getContentId().equals(id.value())) {
                     checkMediaTypes(a.getContentType(), id.type());
                     return a;    
@@ -86,6 +109,19 @@
         return infos.size() > 0 ? infos.get(0) : null; 
     }
 
+    @SuppressWarnings("unchecked")
+    public static <T> MultivaluedMap<String, T> populateFormMap(MessageContext
mc, Class<T> cls) {
+        MultivaluedMap<String, T> data = new MetadataMap<String, T>();
+        FormUtils.populateMapFromMultipart((MultivaluedMap)data, 
+                                           AttachmentUtils.getMultipartBody(mc), true);
+        return data;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static MultivaluedMap<String, String> populateFormMap(MessageContext mc)
{
+        return populateFormMap(mc, String.class);
+    }
+    
     private static Map<String, Attachment> fromListToMap(List<Attachment> atts)
{
         Map<String, Attachment> map = new LinkedHashMap<String, Attachment>();
         for (Attachment a : atts) {

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBodyTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBodyTest.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBodyTest.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBodyTest.java
Fri Jan 30 18:23:52 2009
@@ -43,6 +43,17 @@
         assertEquals(atts.get(1), b.getChildAttachments().get(0));
     }
     
+    @Test
+    public void testGetAttachmentsById() {
+        List<Attachment> atts = new ArrayList<Attachment>();
+        atts.add(createAttachment("p1"));
+        atts.add(createAttachment("p2"));
+        MultipartBody b = new MultipartBody(atts);
+        assertEquals(atts.get(0), b.getAttachment("p1"));
+        assertEquals(atts.get(1), b.getAttachment("p2"));
+        assertNull(b.getAttachment("p3"));
+    }
+    
     private Attachment createAttachment(String id) {
         return new Attachment(id, 
                        new DataHandler(new ByteArrayDataSource(new byte[]{1}, "application/octet-stream")),

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProviderTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProviderTest.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProviderTest.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingReaderProviderTest.java
Fri Jan 30 18:23:52 2009
@@ -27,10 +27,12 @@
 import javax.ws.rs.Consumes;
 import javax.ws.rs.Encoded;
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 
 import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -49,7 +51,8 @@
     public void testReadFrom() throws Exception {
         InputStream is = getClass().getResourceAsStream("singleValPostBody.txt");
         MultivaluedMap<String, String> mvMap = 
-            ferp.readFrom((Class)MultivaluedMap.class, null, new Annotation[]{}, null, null,
is);
+            (MultivaluedMap<String, String>)ferp.readFrom((Class)MultivaluedMap.class,
null, 
+                new Annotation[]{}, MediaType.APPLICATION_FORM_URLENCODED_TYPE, null, is);
         assertEquals("Wrong entry for foo", "bar", mvMap.getFirst("foo"));
         assertEquals("Wrong entry for boo", "far", mvMap.getFirst("boo"));
 
@@ -61,9 +64,9 @@
         String values = "foo=1+2&bar=1+3";
         
         MultivaluedMap<String, String> mvMap = 
-            ferp.readFrom((Class)MultivaluedMap.class, null, 
-                          new Annotation[]{}, null, null, 
-                          new ByteArrayInputStream(values.getBytes()));
+            (MultivaluedMap<String, String>)ferp.readFrom((Class)MultivaluedMap.class,
null, 
+                new Annotation[]{}, MediaType.APPLICATION_FORM_URLENCODED_TYPE, null, 
+                new ByteArrayInputStream(values.getBytes()));
         assertEquals("Wrong entry for foo", "1 2", mvMap.getFirst("foo"));
         assertEquals("Wrong entry for boo", "1 3", mvMap.getFirst("bar"));
 
@@ -75,9 +78,10 @@
         String values = "foo=1+2&bar=1+3";
         
         MultivaluedMap<String, String> mvMap = 
-            ferp.readFrom((Class)MultivaluedMap.class, null, 
-                          new Annotation[]{CustomMap.class.getAnnotations()[0]}, null, null,

-                          new ByteArrayInputStream(values.getBytes()));
+            (MultivaluedMap<String, String>)ferp.readFrom((Class)MultivaluedMap.class,
null, 
+                new Annotation[]{CustomMap.class.getAnnotations()[0]}, 
+                    MediaType.APPLICATION_FORM_URLENCODED_TYPE, null, 
+                    new ByteArrayInputStream(values.getBytes()));
         assertEquals("Wrong entry for foo", "1+2", mvMap.getFirst("foo"));
         assertEquals("Wrong entry for boo", "1+3", mvMap.getFirst("bar"));
 
@@ -89,7 +93,8 @@
         String values = "foo=1+2&bar=1+3&baz=4";
         
         MultivaluedMap<String, String> mvMap = 
-            ferp.readFrom((Class)CustomMap.class, null, new Annotation[]{}, null, null, 
+            (MultivaluedMap<String, String>)ferp.readFrom((Class)CustomMap.class, null,

+                          new Annotation[]{}, MediaType.APPLICATION_FORM_URLENCODED_TYPE,
null, 
                           new ByteArrayInputStream(values.getBytes()));
         assertEquals(3, mvMap.size());
         assertEquals(1,  mvMap.get("foo").size());
@@ -107,8 +112,8 @@
         String values = "foo=1+2&bar=line1%0D%0Aline+2&baz=4";
         
         MultivaluedMap<String, String> mvMap = 
-            ferp.readFrom((Class)CustomMap.class, null, 
-                          new Annotation[]{}, null, null, 
+            (MultivaluedMap<String, String>)ferp.readFrom((Class)CustomMap.class, null,

+                          new Annotation[]{}, MediaType.APPLICATION_FORM_URLENCODED_TYPE,
null, 
                           new ByteArrayInputStream(values.getBytes()));
         assertEquals(3, mvMap.size());
         assertEquals(1,  mvMap.get("foo").size());
@@ -123,12 +128,13 @@
     
     @SuppressWarnings("unchecked")
     @Test
-    public void testvalidation() throws Exception {
+    public void testValidation() throws Exception {
         ferp.setValidator(new CustomFormValidator());
         String values = "foo=1+2&bar=1+3";
         
         try {
-            ferp.readFrom((Class)CustomMap.class, null, new Annotation[]{}, null, null, 
+            ferp.readFrom((Class)CustomMap.class, null, new Annotation[]{}, 
+                          MediaType.APPLICATION_FORM_URLENCODED_TYPE, null, 
                 new ByteArrayInputStream(values.getBytes()));
             fail();
         } catch (WebApplicationException ex) {
@@ -144,7 +150,8 @@
         InputStream is = getClass().getResourceAsStream("multiValPostBody.txt");
         
         MultivaluedMap<String, String> mvMap = 
-            ferp.readFrom((Class)MultivaluedMap.class, null, new Annotation[]{}, null, null,
is);
+            (MultivaluedMap<String, String>)ferp.readFrom((Class)MultivaluedMap.class,
null,
+                new Annotation[]{}, MediaType.APPLICATION_FORM_URLENCODED_TYPE, null, is);
         List<String> vals = mvMap.get("foo");
 
         assertEquals("Wrong size for foo params", 2, vals.size());

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
(original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
Fri Jan 30 18:23:52 2009
@@ -37,7 +37,7 @@
     @BeforeClass
     public static void startServers() throws Exception {
         assertTrue("server did not launch correctly",
-                   launchServer(MultipartServer.class, true));
+                   launchServer(MultipartServer.class));
     }
     
     @Test
@@ -95,6 +95,42 @@
     }
     
     @Test
+    public void testAddBookAsBody() throws Exception {
+        String address = "http://localhost:9085/bookstore/books/body";
+        doAddBook(address, "attachmentData", 200);               
+    }
+    
+    @Test
+    public void testAddBookFormData() throws Exception {
+        String address = "http://localhost:9085/bookstore/books/form";
+        doAddBook("multipart/form-data", address, "attachmentForm", 200);               
+    }
+    
+    @Test
+    public void testAddBookFormParam() throws Exception {
+        String address = "http://localhost:9085/bookstore/books/formparam";
+        doAddBook("multipart/form-data", address, "attachmentForm", 200);               
+    }
+    
+    @Test
+    public void testAddBookFormBody() throws Exception {
+        String address = "http://localhost:9085/bookstore/books/formbody";
+        doAddBook("multipart/form-data", address, "attachmentForm", 200);               
+    }
+    
+    @Test
+    public void testAddBookFormBody2() throws Exception {
+        String address = "http://localhost:9085/bookstore/books/formbody2";
+        doAddBook("multipart/form-data", address, "attachmentForm", 200);               
+    }
+    
+    @Test
+    public void testAddBookFormParamBean() throws Exception {
+        String address = "http://localhost:9085/bookstore/books/formparambean";
+        doAddBook("multipart/form-data", address, "attachmentForm", 200);               
+    }
+    
+    @Test
     public void testAddBookAsJAXB2() throws Exception {
         String address = "http://localhost:9085/bookstore/books/jaxb2";
         doAddBook(address, "attachmentData", 200);               

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java?rev=739366&r1=739365&r2=739366&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java Fri
Jan 30 18:23:52 2009
@@ -28,11 +28,13 @@
 import javax.activation.DataHandler;
 import javax.activation.DataSource;
 import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Unmarshaller;
@@ -41,6 +43,7 @@
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.ext.multipart.Attachment;
 import org.apache.cxf.jaxrs.ext.multipart.Multipart;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
 import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
 
 @Path("/bookstore")
@@ -64,6 +67,57 @@
     }
     
     @POST
+    @Path("/books/form")
+    @Consumes("multipart/form-data")
+    @Produces("text/xml")
+    public Response addBookFromForm(MultivaluedMap<String, String> data) throws Exception
{
+        Book b = new Book();
+        b.setId(Long.valueOf(data.getFirst("id")));
+        b.setName(data.getFirst("name"));
+        return Response.ok(b).build();
+    }
+    
+    @POST
+    @Path("/books/formbody")
+    @Consumes("multipart/form-data")
+    @Produces("text/xml")
+    public Response addBookFromFormBody(MultipartBody body) throws Exception {
+        MultivaluedMap<String, String> data = AttachmentUtils.populateFormMap(context);
+        Book b = new Book();
+        b.setId(Long.valueOf(data.getFirst("id")));
+        b.setName(data.getFirst("name"));
+        return Response.ok(b).build();
+    }
+    
+    @POST
+    @Path("/books/formbody2")
+    @Consumes("multipart/form-data")
+    @Produces("text/xml")
+    public Response addBookFromFormBody2() throws Exception {
+        return addBookFromFormBody(AttachmentUtils.getMultipartBody(context));
+    }
+    
+    
+    @POST
+    @Path("/books/formparam")
+    @Produces("text/xml")
+    public Response addBookFromFormParam(@FormParam("name") String title, 
+                                         @FormParam("id") Long id) throws Exception {
+        Book b = new Book();
+        b.setId(id);
+        b.setName(title);
+        return Response.ok(b).build();
+    }
+    
+    @POST
+    @Path("/books/formparambean")
+    @Produces("text/xml")
+    public Response addBookFromFormParam(@FormParam("") Book b) throws Exception {
+        return Response.ok(b).build();
+    }
+    
+    
+    @POST
     @Path("/books/istream")
     @Produces("text/xml")
     public Response addBookFromInputStream(InputStream is) throws Exception {
@@ -147,6 +201,14 @@
     }
     
     @POST
+    @Path("/books/body")
+    @Produces("text/xml")
+    public Response addBookFromListOfAttachments(MultipartBody body)  
+        throws Exception {
+        return addBookFromListOfAttachments(body.getAllAttachments());
+    }
+    
+    @POST
     @Path("/books/lististreams")
     @Produces("text/xml")
     public Response addBookFromListOfStreams(List<InputStream> atts)  

Added: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentForm
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentForm?rev=739366&view=auto
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentForm (added)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentForm Fri Jan 30
18:23:52 2009
@@ -0,0 +1,10 @@
+
+------=_Part_4_701508.1145579811786
+Content-Disposition: form-data; name="name"
+
+CXF+in+Action+-+2
+------=_Part_4_701508.1145579811786
+Content-Disposition: form-data ; name = "id"
+
+124
+------=_Part_4_701508.1145579811786--
\ No newline at end of file



Mime
View raw message