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 2010/03/19 18:35:57 UTC

svn commit: r925348 - in /cxf/branches/2.2.x-fixes: ./ rt/core/src/main/java/org/apache/cxf/attachment/ rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/attachment/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ systests/jaxrs/src/...

Author: sergeyb
Date: Fri Mar 19 17:35:57 2010
New Revision: 925348

URL: http://svn.apache.org/viewvc?rev=925348&view=rev
Log:
Merged revisions 925337 via svnmerge from 
https://svn.apache.org/repos/asf/cxf/trunk

........
  r925337 | sergeyb | 2010-03-19 17:09:01 +0000 (Fri, 19 Mar 2010) | 1 line
  
  JAXRS: support for XOP
........

Added:
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBAttachmentMarshaller.java
      - copied unchanged from r925337, cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBAttachmentMarshaller.java
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBAttachmentUnmarshaller.java
      - copied unchanged from r925337, cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBAttachmentUnmarshaller.java
    cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/XopType.java
      - copied unchanged from r925337, cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/XopType.java
Modified:
    cxf/branches/2.2.x-fixes/   (props changed)
    cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
    cxf/branches/2.2.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/attachment/JAXBAttachmentMarshaller.java
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java
    cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
    cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java

Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
    svn:mergeinfo = /cxf/trunk:925337

Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.

Modified: cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java?rev=925348&r1=925347&r2=925348&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java (original)
+++ cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java Fri Mar 19 17:35:57 2010
@@ -19,6 +19,7 @@
 
 package org.apache.cxf.attachment;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
@@ -37,10 +38,12 @@ import java.util.UUID;
 
 import javax.activation.DataHandler;
 import javax.activation.DataSource;
+import javax.activation.FileDataSource;
 import javax.mail.Header;
 import javax.mail.internet.InternetHeaders;
 
 import org.apache.cxf.helpers.HttpHeaderHelper;
+import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.message.Attachment;
 
 public final class AttachmentUtil {
@@ -188,5 +191,69 @@ public final class AttachmentUtil {
         }
         return false;
     }
+
+    public static Attachment createMtomAttachment(boolean isXop, String mimeType, String elementNS, 
+                                                 byte[] data, int offset, int length, int threshold) {
+        if (!isXop || length < threshold) {
+            return null;
+        }        
+        if (mimeType == null) {
+            mimeType = "application/octet-stream";
+        }
+        
+        ByteDataSource source = new ByteDataSource(data, offset, length);
+        source.setContentType(mimeType);
+        DataHandler handler = new DataHandler(source);
+
+        String id;
+        try {
+            id = AttachmentUtil.createContentID(elementNS);
+        } catch (UnsupportedEncodingException e) {
+            throw new Fault(e);
+        }
+        AttachmentImpl att = new AttachmentImpl(id, handler);
+        att.setXOP(isXop);
+        return att;
+    }
+    
+    public static Attachment createMtomAttachmentFromDH(
+        boolean isXop, DataHandler handler, String elementNS, int threshold) {
+        if (!isXop) {
+            return null;
+        }        
+
+        // The following is just wrong. Even if the DataHandler has a stream, we should still
+        // apply the threshold.
+        try {
+            DataSource ds = handler.getDataSource();
+            if (ds instanceof FileDataSource) {
+                FileDataSource fds = (FileDataSource)ds;
+                File file = fds.getFile();
+                if (file.length() < threshold) {
+                    return null;
+                }
+            } else if (ds.getClass().getName().endsWith("ObjectDataSource")) {
+                Object o = handler.getContent();
+                if (o instanceof String 
+                    && ((String)o).length() < threshold) {
+                    return null;
+                } else if (o instanceof byte[] && ((byte[])o).length < threshold) {
+                    return null;
+                }
+            }
+        } catch (IOException e1) {
+        //      ignore, just do the normal attachment thing
+        }
+        
+        String id;
+        try {
+            id = AttachmentUtil.createContentID(elementNS);
+        } catch (UnsupportedEncodingException e) {
+            throw new Fault(e);
+        }
+        AttachmentImpl att = new AttachmentImpl(id, handler);
+        att.setXOP(isXop);
+        return att;
+    }
     
 }

Modified: cxf/branches/2.2.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/attachment/JAXBAttachmentMarshaller.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/attachment/JAXBAttachmentMarshaller.java?rev=925348&r1=925347&r2=925348&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/attachment/JAXBAttachmentMarshaller.java (original)
+++ cxf/branches/2.2.x-fixes/rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/attachment/JAXBAttachmentMarshaller.java Fri Mar 19 17:35:57 2010
@@ -19,22 +19,15 @@
 
 package org.apache.cxf.jaxb.attachment;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.util.Collection;
 import java.util.UUID;
 
 import javax.activation.DataHandler;
-import javax.activation.DataSource;
-import javax.activation.FileDataSource;
 import javax.xml.bind.attachment.AttachmentMarshaller;
 import javax.xml.namespace.QName;
 
 import org.apache.cxf.attachment.AttachmentImpl;
 import org.apache.cxf.attachment.AttachmentUtil;
-import org.apache.cxf.attachment.ByteDataSource;
-import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.message.Attachment;
 
 public class JAXBAttachmentMarshaller extends AttachmentMarshaller {
@@ -60,74 +53,27 @@ public class JAXBAttachmentMarshaller ex
     public String addMtomAttachment(byte[] data, int offset, int length, String mimeType, String elementNS,
                                     String elementLocalName) {
         
-        if (!isXop) {
+        Attachment att = AttachmentUtil.createMtomAttachment(
+                             isXop, mimeType, elementNS, data, offset, length, threshold);
+        if (att != null) {
+            atts.add(att);
+            lastElementName = new QName(elementNS, elementLocalName);
+            return "cid:" + att.getId();
+        } else {
             return null;
-        }        
-        if (mimeType == null) {
-            mimeType = "application/octet-stream";
         }
-        if (length < threshold) {
-            return null;
-        }
-        ByteDataSource source = new ByteDataSource(data, offset, length);
-        source.setContentType(mimeType);
-        DataHandler handler = new DataHandler(source);
-
-        String id;
-        try {
-            id = AttachmentUtil.createContentID(elementNS);
-        } catch (UnsupportedEncodingException e) {
-            throw new Fault(e);
-        }
-        AttachmentImpl att = new AttachmentImpl(id, handler);
-        att.setXOP(this.isXop);
-        atts.add(att);
-
-        lastElementName = new QName(elementNS, elementLocalName);
-        return "cid:" + id;
     }
 
     public String addMtomAttachment(DataHandler handler, String elementNS, String elementLocalName) {
 
-        if (!isXop) {
+        Attachment att = AttachmentUtil.createMtomAttachmentFromDH(isXop, handler, elementNS, threshold);
+        if (att != null) {
+            atts.add(att);
+            lastElementName = new QName(elementNS, elementLocalName);
+            return "cid:" + att.getId();
+        } else {
             return null;
-        }        
-
-        // The following is just wrong. Even if the DataHandler has a stream, we should still
-        // apply the threshold.
-        try {
-            DataSource ds = handler.getDataSource();
-            if (ds instanceof FileDataSource) {
-                FileDataSource fds = (FileDataSource)ds;
-                File file = fds.getFile();
-                if (file.length() < threshold) {
-                    return null;
-                }
-            } else if (ds.getClass().getName().endsWith("ObjectDataSource")) {
-                Object o = handler.getContent();
-                if (o instanceof String 
-                    && ((String)o).length() < threshold) {
-                    return null;
-                } else if (o instanceof byte[] && ((byte[])o).length < threshold) {
-                    return null;
-                }
-            }
-        } catch (IOException e1) {
-        //      ignore, just do the normal attachment thing
-        }
-        
-        String id;
-        try {
-            id = AttachmentUtil.createContentID(elementNS);
-        } catch (UnsupportedEncodingException e) {
-            throw new Fault(e);
         }
-        AttachmentImpl att = new AttachmentImpl(id, handler);
-        att.setXOP(this.isXop);
-        atts.add(att);
-        lastElementName = new QName(elementNS, elementLocalName);
-
-        return "cid:" + id;
     }
 
     @Override

Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=925348&r1=925347&r2=925348&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java Fri Mar 19 17:35:57 2010
@@ -52,10 +52,13 @@ import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.stream.StreamSource;
 
+import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.jaxb.NamespaceMapper;
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.utils.InjectionUtils;
 import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler;
+import org.apache.cxf.message.Attachment;
+import org.apache.cxf.message.Message;
 import org.apache.cxf.staxutils.DepthXMLStreamReader;
 import org.apache.cxf.staxutils.StaxUtils;
 
@@ -148,6 +151,7 @@ public class JAXBElementProvider extends
             if (eventHandler != null) {
                 unmarshaller.setEventHandler(eventHandler);
             }
+            addAttachmentUnmarshaller(unmarshaller);
             Object response = null;
             if (JAXBElement.class.isAssignableFrom(type) 
                 || unmarshalAsJaxbElement 
@@ -310,9 +314,37 @@ public class JAXBElementProvider extends
         }
         
         Marshaller ms = createMarshaller(obj, cls, genericType, enc);
+        addAttachmentMarshaller(ms);
         marshal(obj, cls, genericType, enc, os, mt, ms);
     }
     
+    protected void addAttachmentMarshaller(Marshaller ms) {
+        Collection<Attachment> attachments = getAttachments();
+        if (attachments != null) {
+            Object value = getContext().getContextualProperty(Message.MTOM_THRESHOLD);
+            Integer threshold = value != null ? Integer.valueOf(value.toString()) : 0;
+            ms.setAttachmentMarshaller(new JAXBAttachmentMarshaller(
+                attachments, threshold));
+        }
+    }
+    
+    protected void addAttachmentUnmarshaller(Unmarshaller um) {
+        Collection<Attachment> attachments = getAttachments();
+        if (attachments != null) {
+            um.setAttachmentUnmarshaller(new JAXBAttachmentUnmarshaller(
+                attachments));
+        }
+    }
+    
+    private Collection<Attachment> getAttachments() {
+        MessageContext mc = getContext();
+        if (mc != null) {
+            return CastUtils.cast((Collection<?>)mc.get(Message.ATTACHMENTS));
+        } else {
+            return null;
+        }
+    }
+    
     protected void marshal(Object obj, Class<?> cls, Type genericType, 
                            String enc, OutputStream os, MediaType mt, Marshaller ms)
         throws Exception {

Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java?rev=925348&r1=925347&r2=925348&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java Fri Mar 19 17:35:57 2010
@@ -60,6 +60,8 @@ import org.apache.cxf.jaxrs.impl.Metadat
 import org.apache.cxf.jaxrs.utils.AnnotationUtils;
 import org.apache.cxf.jaxrs.utils.InjectionUtils;
 import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
 
 @Provider
 @Consumes({"multipart/related", "multipart/mixed", "multipart/alternative", "multipart/form-data" })
@@ -334,7 +336,11 @@ public class MultipartProvider extends A
             mimeType = id.type();
         }
         if (mimeType == null) {
-            mimeType = MediaType.APPLICATION_OCTET_STREAM;
+            if (MessageUtils.isTrue(mc.getContextualProperty(Message.MTOM_ENABLED))) {
+                mimeType = "text/xml";
+            } else {
+                mimeType = MediaType.APPLICATION_OCTET_STREAM;
+            }
         }
         return mimeType;
     }

Modified: cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java?rev=925348&r1=925347&r2=925348&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java (original)
+++ cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java Fri Mar 19 17:35:57 2010
@@ -19,16 +19,21 @@
 
 package org.apache.cxf.systest.jaxrs;
 
+import java.awt.Image;
 import java.io.File;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.activation.DataHandler;
+import javax.imageio.ImageIO;
+import javax.mail.util.ByteArrayDataSource;
 import javax.ws.rs.core.MediaType;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Unmarshaller;
@@ -39,6 +44,7 @@ import org.apache.commons.httpclient.met
 import org.apache.commons.httpclient.methods.RequestEntity;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.cxf.jaxrs.ext.multipart.Attachment;
 import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
@@ -238,6 +244,46 @@ public class JAXRSMultipartTest extends 
     }
     
     @Test
+    public void testXopWebClient() throws Exception {
+        String address = "http://localhost:9085/bookstore/xop";
+        JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+        bean.setAddress(address);
+        bean.setProperties(Collections.singletonMap(org.apache.cxf.message.Message.MTOM_ENABLED, 
+                                                    (Object)"true"));
+        WebClient client = bean.createWebClient();
+        HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();
+        conduit.getClient().setReceiveTimeout(1000000);
+        conduit.getClient().setConnectionTimeout(1000000);
+        
+        client.type("multipart/related").accept("text/plain");
+        XopType xop = new XopType();
+        xop.setName("xopName");
+        InputStream is = 
+            getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/book.xsd");
+        byte[] data = IOUtils.readBytesFromStream(is);
+        xop.setAttachinfo(new DataHandler(new ByteArrayDataSource(data, "application/octet-stream")));
+        
+        String bookXsd = IOUtils.readStringFromStream(getClass().getResourceAsStream(
+            "/org/apache/cxf/systest/jaxrs/resources/book.xsd"));
+        xop.setAttachinfo2(bookXsd.getBytes());
+     
+        if (Boolean.getBoolean("java.awt.headless")) {
+            System.out.println("Running headless. Ignoring an Image property.");
+        } else {
+            xop.setImage(getImage("/org/apache/cxf/systest/jaxrs/resources/java.jpg"));
+        }
+        
+        String response = client.post(xop, String.class);
+        
+        
+        assertEquals("xopName" + bookXsd + bookXsd, response);
+    }
+    
+    private Image getImage(String name) throws Exception {
+        return ImageIO.read(getClass().getResource(name));
+    }
+    
+    @Test
     public void testAddBookJaxbJsonImageWebClient() throws Exception {
         String address = "http://localhost:9085/bookstore/books/jaxbjsonimage";
         WebClient client = WebClient.create(address);
@@ -299,9 +345,7 @@ public class JAXRSMultipartTest extends 
     public void testAddGetJaxbBooksWebClient() throws Exception {
         String address = "http://localhost:9085/bookstore/books/jaxbonly";
         WebClient client = WebClient.create(address);
-        HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();
-        conduit.getClient().setReceiveTimeout(1000000);
-        conduit.getClient().setConnectionTimeout(1000000);
+        
         client.type("multipart/mixed;type=application/xml").accept("multipart/mixed");
         
         Book b = new Book("jaxb", 1L);

Modified: cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java?rev=925348&r1=925347&r2=925348&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java (original)
+++ cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java Fri Mar 19 17:35:57 2010
@@ -43,6 +43,7 @@ import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Unmarshaller;
 import javax.xml.transform.stream.StreamSource;
 
+import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.ext.multipart.Attachment;
 import org.apache.cxf.jaxrs.ext.multipart.Multipart;
@@ -67,6 +68,27 @@ public class MultipartStore {
     }
     
     @POST
+    @Path("/xop")
+    @Consumes("multipart/related")
+    @Produces("text/plain")
+    public String addBookXop(XopType type) throws Exception {
+        if (!"xopName".equals(type.getName())) {
+            throw new RuntimeException("Wrong name property");
+        }
+        String bookXsd = IOUtils.readStringFromStream(type.getAttachinfo().getInputStream());
+        String bookXsd2 = IOUtils.readStringFromStream(
+            getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/book.xsd"));
+        if (!bookXsd.equals(bookXsd2)) {
+            throw new RuntimeException("Wrong attachinfo property");
+        }
+        if (!Boolean.getBoolean("java.awt.headless") && type.getImage() == null) {
+            throw new RuntimeException("Wrong image property");
+        }
+        return type.getName() + bookXsd + new String(type.getAttachinfo2());
+    }
+    
+    
+    @POST
     @Path("/books/formimage")
     @Consumes("multipart/form-data")
     @Produces("multipart/form-data")