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;
     }


Reply via email to