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]