Author: dkulp
Date: Thu Feb 21 10:40:00 2008
New Revision: 629910

URL: http://svn.apache.org/viewvc?rev=629910&view=rev
Log:
[CXF-421, CXF-422, CXF-423, CXF-424] Bunch of updates for Provider based 
attachment handling

Modified:
    
incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/LazyAttachmentCollection.java
    
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchInDatabindingInterceptor.java
    
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchOutDatabindingInterceptor.java
    
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/ContextPropertiesMapping.java
    
incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/support/ContextPropertiesMappingTest.java
    
incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/provider/AttachmentProviderXMLClientServerTest.java
    
incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/provider/AttachmentStreamSourceXMLProvider.java

Modified: 
incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/LazyAttachmentCollection.java
URL: 
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/LazyAttachmentCollection.java?rev=629910&r1=629909&r2=629910&view=diff
==============================================================================
--- 
incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/LazyAttachmentCollection.java
 (original)
+++ 
incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/LazyAttachmentCollection.java
 Thu Feb 21 10:40:00 2008
@@ -19,14 +19,22 @@
 package org.apache.cxf.attachment;
 
 import java.io.IOException;
+import java.util.AbstractCollection;
+import java.util.AbstractSet;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.activation.DataHandler;
 
 import org.apache.cxf.message.Attachment;
 
-public class LazyAttachmentCollection implements Collection<Attachment> {
+public class LazyAttachmentCollection 
+    implements Collection<Attachment> {
+    
     private AttachmentDeserializer deserializer;
     private final List<Attachment> attachments = new ArrayList<Attachment>();
     
@@ -140,7 +148,175 @@
         
         return attachments.toArray(arg0);
     }
+    
+    public Map<String, DataHandler> createDataHandlerMap() {
+        return new LazyAttachmentMap(this);
+    }
+
+    private static class LazyAttachmentMap implements Map<String, DataHandler> 
{
+        LazyAttachmentCollection collection;
+        
+        LazyAttachmentMap(LazyAttachmentCollection c) {
+            collection = c;
+        }
+        
+        public void clear() {
+            collection.clear();
+        }
+
+        public boolean containsKey(Object key) {
+            Iterator<Attachment> it = collection.iterator();
+            while (it.hasNext()) {
+                Attachment at = it.next();
+                if (key.equals(at.getId())) {
+                    return true;
+                }
+            }
+            return false;
+        }
 
+        public boolean containsValue(Object value) {
+            Iterator<Attachment> it = collection.iterator();
+            while (it.hasNext()) {
+                Attachment at = it.next();
+                if (value.equals(at.getDataHandler())) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public DataHandler get(Object key) {
+            Iterator<Attachment> it = collection.iterator();
+            while (it.hasNext()) {
+                Attachment at = it.next();
+                if (key.equals(at.getId())) {
+                    return at.getDataHandler();
+                }
+            }
+            return null;
+        }
+
+        public boolean isEmpty() {
+            return collection.isEmpty();
+        }
+        public int size() {
+            return collection.size();
+        }
+        
+        public DataHandler remove(Object key) {
+            Iterator<Attachment> it = collection.iterator();
+            while (it.hasNext()) {
+                Attachment at = it.next();
+                if (key.equals(at.getId())) {
+                    collection.remove(at);
+                    return at.getDataHandler();
+                }
+            }
+            return null;
+        }
+        public DataHandler put(String key, DataHandler value) {
+            Attachment at = new AttachmentImpl(key, value);
+            collection.add(at);
+            return value;
+        }
+
+        public void putAll(Map<? extends String, ? extends DataHandler> t) {
+            for (Map.Entry<? extends String, ? extends DataHandler> ent : 
t.entrySet()) {
+                put(ent.getKey(), ent.getValue());
+            }
+        }
+
+        
+        public Set<Map.Entry<String, DataHandler>> entrySet() {
+            return new AbstractSet<Map.Entry<String, DataHandler>>() {
+                public Iterator<Map.Entry<String, DataHandler>> iterator() {
+                    return new Iterator<Map.Entry<String, DataHandler>>() {
+                        Iterator<Attachment> it = collection.iterator();
+                        public boolean hasNext() {
+                            return it.hasNext();
+                        }
+                        public Map.Entry<String, DataHandler> next() {
+                            return new Map.Entry<String, DataHandler>() {
+                                Attachment at = it.next();
+                                public String getKey() {
+                                    return at.getId();
+                                }
+                                public DataHandler getValue() {
+                                    return at.getDataHandler();
+                                }
+                                public DataHandler setValue(DataHandler value) 
{
+                                    if (at instanceof AttachmentImpl) {
+                                        DataHandler h = at.getDataHandler();
+                                        
((AttachmentImpl)at).setDataHandler(value);
+                                        return h;
+                                    } else {
+                                        throw new 
UnsupportedOperationException();
+                                    }
+                                }
+                            };
+                        }
+                        public void remove() {
+                            it.remove();
+                        }
+                    };
+                }
+                public int size() {
+                    return collection.size();
+                }
+            };
+        }
+
+        public Set<String> keySet() {
+            return new AbstractSet<String>() {
+                public Iterator<String> iterator() {
+                    return new Iterator<String>() {
+                        Iterator<Attachment> it = collection.iterator();
+                        public boolean hasNext() {
+                            return it.hasNext();
+                        }
+
+                        public String next() {
+                            return it.next().getId();
+                        }
+
+                        public void remove() {
+                            it.remove();
+                        }
+                    };
+                }
+
+                public int size() {
+                    return collection.size();
+                }
+            };
+        }
+
+
+        public Collection<DataHandler> values() {
+            return new AbstractCollection<DataHandler>() {
+                public Iterator<DataHandler> iterator() {
+                    return new Iterator<DataHandler>() {
+                        Iterator<Attachment> it = collection.iterator();
+                        public boolean hasNext() {
+                            return it.hasNext();
+                        }
+                        public DataHandler next() {
+                            return it.next().getDataHandler();
+                        }
+                        public void remove() {
+                            it.remove();
+                        }
+                    };
+                }
+
+                public int size() {
+                    return collection.size();
+                }
+            };
+        }
+        
+    }
 
 
 }

Modified: 
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchInDatabindingInterceptor.java
URL: 
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchInDatabindingInterceptor.java?rev=629910&r1=629909&r2=629910&view=diff
==============================================================================
--- 
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchInDatabindingInterceptor.java
 (original)
+++ 
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchInDatabindingInterceptor.java
 Thu Feb 21 10:40:00 2008
@@ -60,6 +60,7 @@
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.helpers.XMLUtils;
 import org.apache.cxf.interceptor.AbstractInDatabindingInterceptor;
+import org.apache.cxf.interceptor.AttachmentInInterceptor;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.interceptor.StaxInInterceptor;
 import org.apache.cxf.io.CachedOutputStream;
@@ -151,6 +152,7 @@
                     //LogicalHandler for DataSource payload
                     message.setContent(DataSource.class, obj);  
                 } else {                 
+                    new AttachmentInInterceptor().handleMessage(message);
                     new StaxInInterceptor().handleMessage(message);
                     
                     DataReader<XMLStreamReader> dataReader = new 
XMLStreamDataReader();

Modified: 
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchOutDatabindingInterceptor.java
URL: 
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchOutDatabindingInterceptor.java?rev=629910&r1=629909&r2=629910&view=diff
==============================================================================
--- 
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchOutDatabindingInterceptor.java
 (original)
+++ 
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchOutDatabindingInterceptor.java
 Thu Feb 21 10:40:00 2008
@@ -64,6 +64,7 @@
 import org.apache.cxf.helpers.XMLUtils;
 import org.apache.cxf.interceptor.AbstractInDatabindingInterceptor;
 import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
+import org.apache.cxf.interceptor.AttachmentOutInterceptor;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.jaxws.handler.logical.DispatchLogicalHandlerInterceptor;
 import org.apache.cxf.message.Attachment;
@@ -231,8 +232,7 @@
             super(Phase.WRITE_ENDING);
         }
         
-        public void handleMessage(Message message) throws Fault {
-            OutputStream os = message.getContent(OutputStream.class);
+        public void handleMessage(Message message) throws Fault {              
  
             
             XMLStreamWriter xmlWriter = 
message.getContent(XMLStreamWriter.class);
             SOAPMessage soapMessage = message.getContent(SOAPMessage.class);
@@ -264,15 +264,28 @@
                             l.add(head.getValue());
                         }
                     }
+                    OutputStream os = message.getContent(OutputStream.class);
                     soapMessage.writeTo(os);
+                    os.flush();
                 } else if (source != null) {
+                    if (message.getAttachments() != null
+                        && !message.getAttachments().isEmpty()) {
+                        
message.put(AttachmentOutInterceptor.WRITE_ATTACHMENTS, Boolean.TRUE);
+                        new AttachmentOutInterceptor().handleMessage(message);
+                    }
+                    OutputStream os = message.getContent(OutputStream.class);
                     doTransform(source, os);
+                    os.flush();
                 } else if (dataSource != null) {
+                    if (message.getAttachments() != null
+                        && !message.getAttachments().isEmpty()) {
+                        
message.put(AttachmentOutInterceptor.WRITE_ATTACHMENTS, Boolean.TRUE);
+                        new AttachmentOutInterceptor().handleMessage(message);
+                    }
+                    OutputStream os = message.getContent(OutputStream.class);
                     doTransform(dataSource, os);
+                    os.flush();
                 }
-
-                // Finish the message processing, do flush
-                os.flush();
             } catch (Exception ex) {
                 ex.printStackTrace();
                 throw new Fault(new 
org.apache.cxf.common.i18n.Message("EXCEPTION_WRITING_OBJECT", LOG, ex));

Modified: 
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/ContextPropertiesMapping.java
URL: 
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/ContextPropertiesMapping.java?rev=629910&r1=629909&r2=629910&view=diff
==============================================================================
--- 
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/ContextPropertiesMapping.java
 (original)
+++ 
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/support/ContextPropertiesMapping.java
 Thu Feb 21 10:40:00 2008
@@ -18,8 +18,8 @@
  */
 package org.apache.cxf.jaxws.support;
 
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -31,6 +31,8 @@
 import javax.xml.ws.handler.MessageContext;
 import javax.xml.ws.handler.MessageContext.Scope;
 
+import org.apache.cxf.attachment.AttachmentImpl;
+import org.apache.cxf.attachment.LazyAttachmentCollection;
 import org.apache.cxf.binding.soap.SoapBindingConstants;
 import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.configuration.security.AuthorizationPolicy;
@@ -235,17 +237,20 @@
 
         Collection<Attachment> attachments = message.getAttachments();
         if (attachments != null) {
-            
-            //preserve the order of iteration
-            dataHandlers = new LinkedHashMap<String, DataHandler>();
-            for (Attachment attachment : attachments) {
-                dataHandlers.put(attachment.getId(), 
attachment.getDataHandler());
+            if (attachments instanceof LazyAttachmentCollection) {
+                dataHandlers = 
((LazyAttachmentCollection)attachments).createDataHandlerMap();
+            } else {
+                //preserve the order of iteration
+                dataHandlers = new LinkedHashMap<String, DataHandler>();
+                for (Attachment attachment : attachments) {
+                    dataHandlers.put(attachment.getId(), 
attachment.getDataHandler());
+                }
             }
         }
 
         ctx.put(propertyName, 
-                dataHandlers == null ? Collections.EMPTY_MAP
-                                     : 
Collections.unmodifiableMap(dataHandlers),
+                dataHandlers == null ? new LinkedHashMap<String, DataHandler>()
+                                     : dataHandlers,
                 Scope.APPLICATION);
     }
     
@@ -276,9 +281,27 @@
             } else if (!other.isEmpty()) {
                 exchange.getOutMessage().put(Message.PROTOCOL_HEADERS, 
                                              
ctx.get(MessageContext.HTTP_RESPONSE_HEADERS));
+                heads = other;
+            }
+            if (heads.containsKey("Content-Type")) {
+                List<String> ct = heads.get("Content-Type");
+                exchange.getOutMessage().put(Message.CONTENT_TYPE, ct.get(0));
+                heads.remove("Content-Type");
+            }
+        }
+        Map<String, DataHandler> dataHandlers  
+            = CastUtils.cast((Map<?, 
?>)ctx.get(MessageContext.OUTBOUND_MESSAGE_ATTACHMENTS));
+        if (dataHandlers != null && !dataHandlers.isEmpty()) {
+            Collection<Attachment> attachments = 
exchange.getOutMessage().getAttachments();
+            if (attachments == null) {
+                attachments = new ArrayList<Attachment>();
+                exchange.getOutMessage().setAttachments(attachments);
+            }
+            for (Map.Entry<String, DataHandler> entry : 
dataHandlers.entrySet()) {
+                Attachment att = new AttachmentImpl(entry.getKey(), 
entry.getValue());
+                attachments.add(att);
             }
         }
     }
-   
 
 }

Modified: 
incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/support/ContextPropertiesMappingTest.java
URL: 
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/support/ContextPropertiesMappingTest.java?rev=629910&r1=629909&r2=629910&view=diff
==============================================================================
--- 
incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/support/ContextPropertiesMappingTest.java
 (original)
+++ 
incubator/cxf/trunk/rt/frontend/jaxws/src/test/java/org/apache/cxf/jaxws/support/ContextPropertiesMappingTest.java
 Thu Feb 21 10:40:00 2008
@@ -148,6 +148,9 @@
 
         ctx.containsKey(MessageContext.HTTP_RESPONSE_HEADERS);
         EasyMock.expectLastCall().andReturn(false);
+        
+        ctx.get(MessageContext.OUTBOUND_MESSAGE_ATTACHMENTS);
+        EasyMock.expectLastCall().andReturn(null);
 
         EasyMock.replay(ctx);
         

Modified: 
incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/provider/AttachmentProviderXMLClientServerTest.java
URL: 
http://svn.apache.org/viewvc/incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/provider/AttachmentProviderXMLClientServerTest.java?rev=629910&r1=629909&r2=629910&view=diff
==============================================================================
--- 
incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/provider/AttachmentProviderXMLClientServerTest.java
 (original)
+++ 
incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/provider/AttachmentProviderXMLClientServerTest.java
 Thu Feb 21 10:40:00 2008
@@ -23,18 +23,15 @@
 import java.net.HttpURLConnection;
 import java.net.URL;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
 import org.apache.cxf.common.util.Base64Utility;
 import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.helpers.XMLUtils;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class AttachmentProviderXMLClientServerTest extends 
AbstractBusClientServerTestBase {
@@ -46,7 +43,6 @@
     }
 
     @Test
-    @Ignore("REVISIT: I do not think it is valid to use Provider to receive a 
StreamSource with attachement")
     public void testRequestWithAttachment() throws Exception {
         
         HttpURLConnection connection =  
@@ -63,20 +59,28 @@
         IOUtils.copy(is, connection.getOutputStream());
         connection.getOutputStream().close();
         is.close();
+
+        assertTrue("wrong content type", 
connection.getContentType().contains("multipart/related"));
+        String input = IOUtils.toString(connection.getInputStream());
         
-        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        DocumentBuilder builder = factory.newDocumentBuilder();
-        assertEquals("wrong content type", "application/xml+custom", 
connection.getContentType());
-        Document result = builder.parse(connection.getInputStream());
-        assertNotNull("result must not be null", result);
+        int idx = input.indexOf("-----");
+        int idx2 = input.indexOf("-----", idx + 5);
+        String root = input.substring(idx, idx2);
+        idx = root.indexOf("\r\n\r\n");
+        root = root.substring(idx).trim();
         
-        connection.getInputStream().close();
+
+        Document result = XMLUtils.parse(root);
         
         NodeList resList = 
result.getDocumentElement().getElementsByTagName("att");
         assertEquals("Two attachments must've been encoded", 2, 
resList.getLength());
         
         verifyAttachment(resList, "foo", "foobar");
         verifyAttachment(resList, "bar", "barbaz");
+        
+        input = input.substring(idx2);
+        assertTrue(input.contains("<foo>"));
+        assertTrue(input.contains("ABCDEFGHIJKLMNOP"));
     }
 
     private void verifyAttachment(NodeList atts, String contentId, String 
value) {

Modified: 
incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/provider/AttachmentStreamSourceXMLProvider.java
URL: 
http://svn.apache.org/viewvc/incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/provider/AttachmentStreamSourceXMLProvider.java?rev=629910&r1=629909&r2=629910&view=diff
==============================================================================
--- 
incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/provider/AttachmentStreamSourceXMLProvider.java
 (original)
+++ 
incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/provider/AttachmentStreamSourceXMLProvider.java
 Thu Feb 21 10:40:00 2008
@@ -31,6 +31,7 @@
 
 import javax.activation.DataHandler;
 import javax.annotation.Resource;
+import javax.mail.util.ByteArrayDataSource;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.dom.DOMResult;
 import javax.xml.transform.stream.StreamSource;
@@ -111,6 +112,15 @@
             List<String> contentTypeValues = new ArrayList<String>();
             contentTypeValues.add("application/xml+custom");
             respHeaders.put(Message.CONTENT_TYPE, contentTypeValues);
+
+            Map<String, DataHandler> outDataHandlers 
+                = 
CastUtils.cast((Map)mc.get(MessageContext.OUTBOUND_MESSAGE_ATTACHMENTS));
+            byte[] data = new byte[50];
+            for (int x = 0; x < data.length; x++) {
+                data[x] = (byte)(x + (int)'0');
+            }
+            DataHandler foo = new DataHandler(new ByteArrayDataSource(data, 
"application/octet-stream"));
+            outDataHandlers.put("foo", foo);
             
             return new StreamSource(new StringReader(buf.toString()));
         }


Reply via email to