Author: veithen
Date: Sun Oct 16 12:12:22 2011
New Revision: 1184807
URL: http://svn.apache.org/viewvc?rev=1184807&view=rev
Log:
Added a proper API to MTOMXMLStreamWriter that enables integration with third
party libraries that support XOP/MTOM but that need to write the xop:Include
element themselves.
Modified:
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/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?rev=1184807&r1=1184806&r2=1184807&view=diff
==============================================================================
---
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
Sun Oct 16 12:12:22 2011
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.LinkedList;
+import java.util.List;
import javax.activation.DataHandler;
import javax.xml.namespace.NamespaceContext;
@@ -32,6 +33,8 @@ import javax.xml.stream.XMLStreamWriter;
import org.apache.axiom.attachments.impl.BufferUtils;
import org.apache.axiom.attachments.lifecycle.DataHandlerExt;
+import org.apache.axiom.ext.stax.datahandler.DataHandlerProvider;
+import org.apache.axiom.ext.stax.datahandler.DataHandlerWriter;
import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMOutputFormat;
@@ -55,12 +58,33 @@ import org.apache.commons.logging.LogFac
* optimizable content.
*/
public class MTOMXMLStreamWriter implements XMLStreamWriter {
+ /**
+ * Stores a part that has been added without using the {@link
DataHandlerWriter} API.
+ */
+ private static class Part {
+ private final String contentID;
+ private final DataHandler dataHandler;
+
+ public Part(String contentID, DataHandler dataHandler) {
+ this.contentID = contentID;
+ this.dataHandler = dataHandler;
+ }
+
+ public String getContentID() {
+ return contentID;
+ }
+
+ public DataHandler getDataHandler() {
+ return dataHandler;
+ }
+ }
+
private static Log log = LogFactory.getLog(MTOMXMLStreamWriter.class);
private static boolean isDebugEnabled = log.isDebugEnabled();
private static boolean isTraceEnabled = log.isTraceEnabled();
private XMLStreamWriter xmlWriter;
private OutputStream outStream;
- private LinkedList binaryNodeList = new LinkedList();
+ private List/*<Part>*/ otherParts = new LinkedList();
private OMMultipartWriter multipartWriter;
private OutputStream rootPartOutputStream;
private OMOutputFormat format = new OMOutputFormat();
@@ -235,11 +259,10 @@ public class MTOMXMLStreamWriter impleme
out.close();
}
}
- // This is for compatibility with writeOptimized
- for (Iterator it = binaryNodeList.iterator(); it.hasNext();) {
- OMText text = (OMText) it.next();
- multipartWriter.writePart((DataHandler)
text.getDataHandler(),
- text.getContentID());
+ // Now write parts that have been added by prepareDataHandler
+ for (Iterator it = otherParts.iterator(); it.hasNext();) {
+ Part part = (Part)it.next();
+ multipartWriter.writePart(part.getDataHandler(),
part.getContentID());
}
multipartWriter.complete();
} catch (IOException e) {
@@ -362,15 +385,16 @@ public class MTOMXMLStreamWriter impleme
* @deprecated
* Serialization code should use
* {@link XMLStreamWriterUtils#writeDataHandler(XMLStreamWriter,
DataHandler, String, boolean)}
- * or {@link XMLStreamWriterUtils#writeDataHandler(XMLStreamWriter,
org.apache.axiom.ext.stax.datahandler.DataHandlerProvider, String, boolean)}
+ * or {@link XMLStreamWriterUtils#writeDataHandler(XMLStreamWriter,
DataHandlerProvider, String, boolean)}
* to submit any binary content and let this writer decide whether the
content should be
- * written as base64 encoded character data or using <tt>xop:Include</tt>.
+ * written as base64 encoded character data or using <tt>xop:Include</tt>.
If this is not
+ * possible, then {@link #prepareDataHandler(DataHandler)} should be used.
*/
public void writeOptimized(OMText node) {
if(isDebugEnabled){
log.debug("Start MTOMXMLStreamWriter.writeOptimized()");
}
- binaryNodeList.add(node);
+ otherParts.add(new Part(node.getContentID(),
(DataHandler)node.getDataHandler()));
if(isDebugEnabled){
log.debug("Exit MTOMXMLStreamWriter.writeOptimized()");
}
@@ -380,11 +404,13 @@ public class MTOMXMLStreamWriter impleme
* @deprecated
* Serialization code should use
* {@link XMLStreamWriterUtils#writeDataHandler(XMLStreamWriter,
DataHandler, String, boolean)}
- * or {@link XMLStreamWriterUtils#writeDataHandler(XMLStreamWriter,
org.apache.axiom.ext.stax.datahandler.DataHandlerProvider, String, boolean)}
+ * or {@link XMLStreamWriterUtils#writeDataHandler(XMLStreamWriter,
DataHandlerProvider, String, boolean)}
* to submit any binary content and let this writer decide whether the
content should be
- * written as base64 encoded character data or using <tt>xop:Include</tt>.
- * Since the writer applies the settings defined in {@link OMOutputFormat}
(including MTOM
- * thresholds), there is not need for this method anymore.
+ * written as base64 encoded character data or using <tt>xop:Include</tt>.
If this is not
+ * possible, then {@link #prepareDataHandler(DataHandler)} should be used.
+ * All the aforementioned methods take into account the settings defined in
+ * {@link OMOutputFormat} to determine whether the binary data should be
optimized or not.
+ * Therefore, there is not need for this method anymore.
*/
public boolean isOptimizedThreshold(OMText node){
// The optimize argument is set to true for compatibility. Indeed,
older versions
@@ -396,6 +422,45 @@ public class MTOMXMLStreamWriter impleme
}
}
+ /**
+ * Prepare a {@link DataHandler} for serialization without using the
{@link DataHandlerWriter}
+ * API. The method first determines whether the binary data represented by
the
+ * {@link DataHandler} should be optimized or inlined. If the data should
not be optimized, then
+ * the method returns <code>null</code> and the caller is expected to use
+ * {@link #writeCharacters(String)} or {@link #writeCharacters(char[],
int, int)} to write the
+ * base64 encoded data to the stream. If the data should be optimized,
then the method returns a
+ * content ID and the caller is expected to generate an
<tt>xop:Include</tt> element referring
+ * to that content ID.
+ * <p>
+ * This method should only be used to integrate Axiom with third party
libraries that support
+ * XOP. In all other cases,
+ * {@link XMLStreamWriterUtils#writeDataHandler(XMLStreamWriter,
DataHandler, String, boolean)}
+ * or
+ * {@link XMLStreamWriterUtils#writeDataHandler(XMLStreamWriter,
DataHandlerProvider, String, boolean)}
+ * should be used to write base64Binary values and the application code
should never generate
+ * <tt>xop:Include</tt> elements itself.
+ *
+ * @param dataHandler
+ * the {@link DataHandler} that the caller intends to write to
the stream
+ * @return the content ID that the caller must use in the
<tt>xop:Include</tt> element or
+ * <code>null</code> if the base64 encoded data should not be
optimized
+ */
+ public String prepareDataHandler(DataHandler dataHandler) {
+ boolean doOptimize;
+ try {
+ doOptimize = optimizationPolicy.isOptimized(dataHandler, true);
+ } catch (IOException ex) {
+ doOptimize = true;
+ }
+ if (doOptimize) {
+ String contentID = getNextContentId();
+ otherParts.add(new Part(contentID, dataHandler));
+ return contentID;
+ } else {
+ return null;
+ }
+ }
+
public void setXmlStreamWriter(XMLStreamWriter xmlWriter) {
this.xmlWriter = xmlWriter;
}