Author: scheu
Date: Thu Aug  9 08:13:15 2007
New Revision: 564234

URL: http://svn.apache.org/viewvc?view=rev&rev=564234
Log:
WSCOMMONS-231
Contributor:Rich Scheuerle
Upgrades to MTOMXMLStreamWriter

Summary of Changes:
    1) Improve quality of the attachment writing code (make sure attachments 
are not
       written in the middle of the SOAPPart)
    2) Improve access to the OutputStream.
    3) JavaDoc improvements.
  

Modified:
    
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MIMEOutputUtils.java
    
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MTOMXMLStreamWriter.java

Modified: 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MIMEOutputUtils.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MIMEOutputUtils.java?view=diff&rev=564234&r1=564233&r2=564234
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MIMEOutputUtils.java
 (original)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MIMEOutputUtils.java
 Thu Aug  9 08:13:15 2007
@@ -37,20 +37,44 @@
 import org.apache.axiom.soap.SOAP11Constants;
 import org.apache.axiom.soap.SOAP12Constants;
 
+/**
+ * Utility class used to write out XML with Attachments
+ * @See MTOMXMLStreamWriter
+ *
+ */
 public class MIMEOutputUtils {
 
     private static byte[] CRLF = { 13, 10 };
 
-    public static void complete(OutputStream outStream,
-                                StringWriter writer, LinkedList binaryNodeList,
-                                String boundary, String contentId, String 
charSetEncoding,
+    /**
+     * Invoked by MTOMXMLStreamWriter to write the SOAP Part and the attachemts
+     * @param outStream OutputStream target
+     * @param bufferedXML String containing XML of SOAPPart
+     * @param binaryNodeList Text nodes with the attachment Data Handlers
+     * @param boundary Boundary String
+     * @param contentId Content-ID of SOAPPart
+     * @param charSetEncoding Character Encoding of SOAPPart
+     * @param SOAPContentType Content-Type of SOAPPart
+     */
+    public static void complete(OutputStream outStream, 
+                                String bufferedXML,
+                                LinkedList binaryNodeList, 
+                                String boundary, 
+                                String contentId,
+                                String charSetEncoding, 
                                 String SOAPContentType) {
         try {
+            // TODO: Instead of buffering the SOAPPart contents, it makes more
+            // sense to split this method in two.  Write out the SOAPPart 
headers
+            // and later write out the attachments.  This will avoid the cost 
and
+            // space of buffering.
+            
+            // Write out the mime boundary
             startWritingMime(outStream, boundary);
 
-            javax.activation.DataHandler dh = new 
javax.activation.DataHandler(writer.toString(),
-                                                                               
"text/xml; charset=" +
-                                                                               
        charSetEncoding);
+            javax.activation.DataHandler dh = 
+                new javax.activation.DataHandler(bufferedXML,
+                                                 "text/xml; charset=" + 
charSetEncoding);
             MimeBodyPart rootMimeBodyPart = new MimeBodyPart();
             rootMimeBodyPart.setDataHandler(dh);
 
@@ -60,8 +84,11 @@
             rootMimeBodyPart.addHeader("Content-Transfer-Encoding", "binary");
             rootMimeBodyPart.addHeader("Content-ID", "<" + contentId + ">");
 
+            // Write out the SOAPPart
             writeBodyPart(outStream, rootMimeBodyPart, boundary);
 
+            // Now write out the Attachment parts (which are represented by the
+            // text nodes int the binary node list)
             Iterator binaryNodeIterator = binaryNodeList.iterator();
             while (binaryNodeIterator.hasNext()) {
                 OMText binaryNode = (OMText) binaryNodeIterator.next();
@@ -76,6 +103,28 @@
         } catch (MessagingException e) {
             throw new OMException("Problem writing Mime Parts.", e);
         }
+    }
+    
+    /**
+     * Write the SOAPPart and attachments
+     * @param outStream
+     * @param writer
+     * @param binaryNodeList
+     * @param boundary
+     * @param contentId
+     * @param charSetEncoding
+     * @param SOAPContentType
+     */
+    public static void complete(OutputStream outStream, StringWriter writer,
+                                LinkedList binaryNodeList, String boundary, 
String contentId,
+                                String charSetEncoding, String 
SOAPContentType) {
+        complete(outStream, 
+                 writer.toString(), 
+                 binaryNodeList, 
+                 boundary, 
+                 contentId, 
+                 charSetEncoding, 
+                 SOAPContentType);
     }
 
     public static MimeBodyPart createMimeBodyPart(String contentID,

Modified: 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MTOMXMLStreamWriter.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MTOMXMLStreamWriter.java?view=diff&rev=564234&r1=564233&r2=564234
==============================================================================
--- 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MTOMXMLStreamWriter.java
 (original)
+++ 
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/MTOMXMLStreamWriter.java
 Thu Aug  9 08:13:15 2007
@@ -19,6 +19,7 @@
 
 package org.apache.axiom.om.impl;
 
+import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMOutputFormat;
 import org.apache.axiom.om.OMText;
 import org.apache.axiom.om.util.StAXUtils;
@@ -29,12 +30,18 @@
 import javax.xml.stream.FactoryConfigurationError;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.OutputStream;
 import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
 import java.util.LinkedList;
 
 
 /**
+ * MTOMXMLStreamWriter is an XML + Attachments stream writer.
+ * 
  * For the moment this assumes that transport takes the decision of whether to 
optimize or not by
  * looking at whether the MTOM optimize is enabled & also looking at the OM 
tree whether it has any
  * optimizable content.
@@ -43,8 +50,13 @@
     private XMLStreamWriter xmlWriter;
     private OutputStream outStream;
     private LinkedList binaryNodeList = new LinkedList();
-    private StringWriter bufferedSOAPBody;
+    private ByteArrayOutputStream bufferedXML;  // XML for the SOAPPart
     private OMOutputFormat format = new OMOutputFormat();
+    
+    // State variables
+    private boolean isEndDocument = false; // has endElement been called
+    private boolean isComplete = false;    // have the attachments been written
+    private int depth = 0;                 // current eleement depth
 
     public MTOMXMLStreamWriter(XMLStreamWriter xmlWriter) {
         this.xmlWriter = xmlWriter;
@@ -68,8 +80,9 @@
             
format.setCharSetEncoding(OMOutputFormat.DEFAULT_CHAR_SET_ENCODING);
 
         if (format.isOptimized()) {
-            bufferedSOAPBody = new StringWriter();
-            xmlWriter = StAXUtils.createXMLStreamWriter(bufferedSOAPBody);
+            // REVIEW If the buffered XML gets too big, should it be written 
out to a file 
+            bufferedXML = new ByteArrayOutputStream();
+            xmlWriter = 
StAXUtils.createXMLStreamWriter(bufferedXML,format.getCharSetEncoding());
         } else {
             xmlWriter = StAXUtils.createXMLStreamWriter(outStream,
                                                         
format.getCharSetEncoding());
@@ -78,15 +91,18 @@
 
     public void writeStartElement(String string) throws XMLStreamException {
         xmlWriter.writeStartElement(string);
+        depth++;
     }
 
     public void writeStartElement(String string, String string1) throws 
XMLStreamException {
         xmlWriter.writeStartElement(string, string1);
+        depth++;
     }
 
     public void writeStartElement(String string, String string1, String 
string2)
             throws XMLStreamException {
         xmlWriter.writeStartElement(string, string1, string2);
+        depth++;
     }
 
     public void writeEmptyElement(String string, String string1) throws 
XMLStreamException {
@@ -104,34 +120,54 @@
 
     public void writeEndElement() throws XMLStreamException {
         xmlWriter.writeEndElement();
+        depth--;
     }
 
     public void writeEndDocument() throws XMLStreamException {
         xmlWriter.writeEndDocument();
+        isEndDocument = true; 
     }
 
     public void close() throws XMLStreamException {
         xmlWriter.close();
     }
 
+    /**
+     * Flush is overridden to trigger the attachment serialization
+     */
     public void flush() throws XMLStreamException {
         xmlWriter.flush();
         String SOAPContentType;
-        if (format.isOptimized()) {
+        // flush() triggers the optimized attachment writing.
+        // If the optimized attachments are specified, and the xml
+        // document is completed, then write out the attachments.
+        if (format.isOptimized() && !isComplete & (isEndDocument || depth == 
0)) {
+            isComplete = true;
             if (format.isSOAP11()) {
                 SOAPContentType = SOAP11Constants.SOAP_11_CONTENT_TYPE;
             } else {
                 SOAPContentType = SOAP12Constants.SOAP_12_CONTENT_TYPE;
             }
-            MIMEOutputUtils.complete(
-                    outStream,
-                    bufferedSOAPBody,
-                    binaryNodeList,
-                    format.getMimeBoundary(),
-                    format.getRootContentId(),
-                    format.getCharSetEncoding(), SOAPContentType);
+            try {
+                String bufferedXMLText =
+                        new String(bufferedXML.toByteArray(), 
format.getCharSetEncoding());
+                MIMEOutputUtils.complete(outStream,
+                                         bufferedXMLText,
+                                         binaryNodeList,
+                                         format.getMimeBoundary(),
+                                         format.getRootContentId(),
+                                         format.getCharSetEncoding(),
+                                         SOAPContentType);
+                bufferedXML.close();
+                bufferedXML = null;
+            } catch (UnsupportedEncodingException e) {
+                throw new OMException(e);
+            } catch (IOException e) {
+                throw new OMException(e);
+            }
         }
     }
+    
 
     public void writeAttribute(String string, String string1) throws 
XMLStreamException {
         xmlWriter.writeAttribute(string, string1);
@@ -305,18 +341,14 @@
      * directly to the OutputStream.
      * @return OutputStream or null
      */
-    public OutputStream getOutputStream() throws XMLStreamException {
-        
-        // TODO: The presence of a bufferedSOAPBody means that we are not 
writing directly to the 
-        // OutputStream.  Need some redesign work here because (a) 
bufferedSOAPBody is not a soap body it 
-        // is the SOAP envelope xml. And (b) probably should make 
bufferedSOAPBody an OutputStream instead
-        // of a StringWriter (and avoid conversions to and from a String).  
And (c) we can change this
-        // code to return the buffered OutputStream.
-        if (bufferedSOAPBody == null) {
-            return null;
+    public OutputStream getOutputStream() throws XMLStreamException {  
+        OutputStream os = null;
+        if (bufferedXML != null) {
+            os = bufferedXML;
+        } else {
+            os = outStream;
         }
-        
-        OutputStream os = outStream;
+       
         if (os != null) {
             // Flush the state of the writer..Many times the 
             // write defers the writing of tag characters (>)



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to