You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-dev@ws.apache.org by sc...@apache.org on 2008/05/13 14:56:37 UTC

svn commit: r655845 - in /webservices/commons/trunk/modules/axiom/modules: axiom-api/src/main/java/org/apache/axiom/om/ axiom-api/src/main/java/org/apache/axiom/soap/impl/builder/ axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ axiom-impl/src/mai...

Author: scheu
Date: Tue May 13 05:56:37 2008
New Revision: 655845

URL: http://svn.apache.org/viewvc?rev=655845&view=rev
Log:
WSCOMMONS-344
Contributor:Rich Scheuerle
Discovered By: Huiran Wang
The OMStAXWrapper code is upgraded to support the delivery of MTOM attachments as XOP:Include elements.  See the discussion in the JIRA

Added:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMXMLStreamReader.java
Modified:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/impl/builder/MTOMStAXSOAPModelBuilder.java
    webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DOMStAXWrapper.java
    webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMStAXWrapper.java
    webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/mtom/MTOMStAXSOAPModelBuilderTest.java

Added: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMXMLStreamReader.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMXMLStreamReader.java?rev=655845&view=auto
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMXMLStreamReader.java (added)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/OMXMLStreamReader.java Tue May 13 05:56:37 2008
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.om;
+
+import javax.xml.stream.XMLStreamReader;
+
+/**
+ * Objects returned by OMElement.getXMLStreamReader may implement this interface
+ */
+/**
+ * @author scheu
+ *
+ */
+public interface OMXMLStreamReader extends XMLStreamReader, OMAttachmentAccessor {
+    
+    /**
+     * By default, an OMText item that has an MTOM datahandler 
+     * will be rendered as a inlined text event.
+     * @return true if inlined as TEXT, false if XOP_INCLUDE is used
+     */
+    public boolean isInlineMTOM();
+    
+    /**
+     * @param value set to true if inlining of text is desired (default)
+     * throw OMException if not the value is not supported.
+     */
+    public void setInlineMTOM(boolean value);
+    
+}

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/impl/builder/MTOMStAXSOAPModelBuilder.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/impl/builder/MTOMStAXSOAPModelBuilder.java?rev=655845&r1=655844&r2=655845&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/impl/builder/MTOMStAXSOAPModelBuilder.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/soap/impl/builder/MTOMStAXSOAPModelBuilder.java Tue May 13 05:56:37 2008
@@ -101,11 +101,15 @@
       */
     public DataHandler getDataHandler(String blobContentID) throws OMException {
         DataHandler dataHandler = attachments.getDataHandler(blobContentID);
+        /* The getDataHandler javadoc indicates that null indicate that the datahandler
+         * was not found
+         * 
         if (dataHandler == null) {
             throw new OMException(
                     "Referenced Attachment not found in the MIME Message. ContentID:"
                             + blobContentID);
         }
+        */
         return dataHandler;
     }
 }

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DOMStAXWrapper.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DOMStAXWrapper.java?rev=655845&r1=655844&r2=655845&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DOMStAXWrapper.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/DOMStAXWrapper.java Tue May 13 05:56:37 2008
@@ -19,20 +19,24 @@
 
 package org.apache.axiom.om.impl.dom;
 
+import org.apache.axiom.om.OMAttachmentAccessor;
 import org.apache.axiom.om.OMAttribute;
 import org.apache.axiom.om.OMComment;
 import org.apache.axiom.om.OMConstants;
 import org.apache.axiom.om.OMDocument;
 import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.OMNode;
 import org.apache.axiom.om.OMText;
 import org.apache.axiom.om.OMXMLParserWrapper;
+import org.apache.axiom.om.OMXMLStreamReader;
 import org.apache.axiom.om.impl.EmptyOMLocation;
 import org.apache.axiom.om.impl.builder.StAXBuilder;
 import org.apache.axiom.om.impl.exception.OMStreamingException;
 import org.w3c.dom.Attr;
 
+import javax.activation.DataHandler;
 import javax.xml.namespace.NamespaceContext;
 import javax.xml.namespace.QName;
 import javax.xml.stream.Location;
@@ -49,7 +53,7 @@
  * Note - This class also implements the streaming constants interface to get access to the StAX
  * constants.
  */
-public class DOMStAXWrapper implements XMLStreamReader, XMLStreamConstants {
+public class DOMStAXWrapper implements OMXMLStreamReader, XMLStreamConstants {
     /** Field navigator */
     private DOMNavigator navigator;
 
@@ -117,6 +121,13 @@
     private OMNode lastNode = null;
 
     private boolean needToThrowEndDocument = false;
+    
+    /** 
+     * If true then TEXT events are constructed for the MTOM attachment
+     * If false, an <xop:Include href="cid:xxxxx"/> event is constructed and
+     * the consumer must call getDataHandler(cid) to access the datahandler.
+     */
+    private boolean inlineMTOM = true;
 
     /**
      * Method setAllowSwitching.
@@ -266,7 +277,8 @@
      * @see javax.xml.stream.XMLStreamReader#hasText()
      */
     public boolean hasText() {
-        return ((currentEvent == CHARACTERS) || (currentEvent == DTD)
+        return ((currentEvent == CHARACTERS) || (currentEvent == DTD) 
+                || (currentEvent == CDATA)
                 || (currentEvent == ENTITY_REFERENCE)
                 || (currentEvent == COMMENT) || (currentEvent == SPACE));
     }
@@ -1208,4 +1220,24 @@
     public void setParser(XMLStreamReader parser) {
         this.parser = parser;
     }
+
+    public DataHandler getDataHandler(String blobcid) {
+        DataHandler dh = null;
+        if (builder != null && 
+                builder instanceof OMAttachmentAccessor) {
+            dh = ((OMAttachmentAccessor) builder).getDataHandler(blobcid);
+        }
+        return dh;
+    }
+
+    public boolean isInlineMTOM() {
+        return inlineMTOM;
+       
+    }
+
+    public void setInlineMTOM(boolean value) {
+        if (value == true) {
+            throw new OMException("setInlineMTOM(true) is not supported");
+        }
+    }
 }

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMStAXWrapper.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMStAXWrapper.java?rev=655845&r1=655844&r2=655845&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMStAXWrapper.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMStAXWrapper.java Tue May 13 05:56:37 2008
@@ -45,6 +45,7 @@
 import org.apache.axiom.om.OMSourcedElement;
 import org.apache.axiom.om.OMText;
 import org.apache.axiom.om.OMXMLParserWrapper;
+import org.apache.axiom.om.OMXMLStreamReader;
 import org.apache.axiom.om.impl.EmptyOMLocation;
 import org.apache.axiom.om.impl.builder.StAXBuilder;
 import org.apache.axiom.om.impl.exception.OMStreamingException;
@@ -57,7 +58,7 @@
  * constants
  */
 public class OMStAXWrapper 
-    implements XMLStreamReader, XMLStreamConstants, OMAttachmentAccessor {
+    implements OMXMLStreamReader, XMLStreamConstants {
     
     private static final Log log = LogFactory.getLog(OMStAXWrapper.class);
     private static boolean DEBUG_ENABLED = log.isDebugEnabled();
@@ -91,6 +92,14 @@
     private static final short COMPLETED = 2;
     private static final short SWITCHED = 3;
     private static final short DOCUMENT_COMPLETE = 4;
+    
+    
+    // Variables used to build an xop:include representation
+    private final static QName XOP_INCLUDE = 
+        new QName("http://www.w3.org/2004/08/xop/include", "Include", "xop");
+    private OMElement xopInclude = null;
+    private OMText xopIncludeText = null;
+    private boolean xopIncludeStart = false;
 
 
     /** Field state */
@@ -113,7 +122,7 @@
     boolean namespaceURIInterning = false;
 
     /** Field elementStack */
-    private Stack elementStack = null;
+    private Stack nodeStack = null;
 
     // keeps the next event. The parser actually keeps one step ahead to
     // detect the end of navigation. (at the end of the stream the navigator
@@ -137,6 +146,13 @@
 
     private boolean needToThrowEndDocument = false;
 
+    /** 
+     * If true then TEXT events are constructed for the MTOM attachment
+     * If false, an <xop:Include href="cid:xxxxx"/> event is constructed and
+     * the consumer must call getDataHandler(cid) to access the datahandler.
+     */
+    private boolean inlineMTOM = true;
+    
     /**
      * Method setAllowSwitching.
      *
@@ -239,7 +255,7 @@
         } else {
             if ((currentEvent == START_ELEMENT)
                     || (currentEvent == END_ELEMENT)) {
-                OMNamespace ns = ((OMElement) lastNode).getNamespace();
+                OMNamespace ns = ((OMElement) getNode()).getNamespace();
                 returnStr = (ns == null)
                         ? null
                         : ns.getPrefix();
@@ -260,7 +276,7 @@
             if ((currentEvent == START_ELEMENT)
                     || (currentEvent == END_ELEMENT)
                     || (currentEvent == NAMESPACE)) {
-                OMNamespace ns = ((OMElement) lastNode).getNamespace();
+                OMNamespace ns = ((OMElement) getNode()).getNamespace();
                 returnStr = (ns == null)
                         ? null
                         : ns.getNamespaceURI();
@@ -303,7 +319,7 @@
             if ((currentEvent == START_ELEMENT)
                     || (currentEvent == END_ELEMENT)
                     || (currentEvent == ENTITY_REFERENCE)) {
-                returnStr = ((OMElement) lastNode).getLocalName();
+                returnStr = ((OMElement) getNode()).getLocalName();
             }
         }
         return returnStr;
@@ -320,7 +336,7 @@
         } else {
             if ((currentEvent == START_ELEMENT)
                     || (currentEvent == END_ELEMENT)) {
-                returnName = getQName((OMElement) lastNode);
+                returnName = getQName((OMElement) getNode());
             }
         }
         return returnName;
@@ -346,7 +362,7 @@
         if (parser != null) {
             returnLength = parser.getTextLength();
         } else {
-            OMText textNode = (OMText) lastNode;
+            OMText textNode = (OMText) getNode();
             returnLength = textNode.getText().length();
         }
         return returnLength;
@@ -386,7 +402,7 @@
             }
         } else {
             if (hasText()) {
-                OMText textNode = (OMText) lastNode;
+                OMText textNode = (OMText) getNode();
                 String str = textNode.getText();
                 str.getChars(i, i + i2, chars, i1);
             }
@@ -404,7 +420,7 @@
             returnArray = parser.getTextCharacters();
         } else {
             if (hasText()) {
-                OMText textNode = (OMText) lastNode;
+                OMText textNode = (OMText) getNode();
                 String str = textNode.getText();
                 returnArray = str.toCharArray();
             }
@@ -422,10 +438,10 @@
             returnString = parser.getText();
         } else {
             if (hasText()) {
-                if (lastNode instanceof OMText) {
-                    returnString = ((OMText) lastNode).getText();
-                } else if (lastNode instanceof OMComment) {
-                    returnString = ((OMComment) lastNode).getValue();
+                if (getNode() instanceof OMText) {
+                    returnString = ((OMText) getNode()).getText();
+                } else if (getNode() instanceof OMComment) {
+                    returnString = ((OMComment) getNode()).getValue();
                 }
             }
         }
@@ -456,7 +472,7 @@
             if (isStartElement() || isEndElement()
                     || (currentEvent == NAMESPACE)) {
                 OMNamespace ns = (OMNamespace) getItemFromIterator(
-                        ((OMElement) lastNode).getAllDeclaredNamespaces(), i);
+                        ((OMElement) getNode()).getAllDeclaredNamespaces(), i);
                 returnString = (ns == null)
                         ? null
                         : ns.getNamespaceURI();
@@ -490,7 +506,7 @@
             if (isStartElement() || isEndElement()
                     || (currentEvent == NAMESPACE)) {
                 OMNamespace ns = (OMNamespace) getItemFromIterator(
-                        ((OMElement) lastNode).getAllDeclaredNamespaces(), i);
+                        ((OMElement) getNode()).getAllDeclaredNamespaces(), i);
                 returnString = (ns == null)
                         ? null
                         : ns.getPrefix();
@@ -512,7 +528,7 @@
                     || (currentEvent == NAMESPACE)) {
                 returnCount =
                         getCount(
-                                ((OMElement) lastNode).getAllDeclaredNamespaces());
+                                ((OMElement) getNode()).getAllDeclaredNamespaces());
             }
         }
         return returnCount;
@@ -550,7 +566,7 @@
             returnString = parser.getAttributeValue(i);
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) lastNode, i);
+                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
                 if (attrib != null) {
                     returnString = attrib.getAttributeValue();
                 }
@@ -574,7 +590,7 @@
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
                 
-            	OMAttribute attrib = getAttribute((OMElement) lastNode, i);
+            	OMAttribute attrib = getAttribute((OMElement) getNode(), i);
                 if (attrib != null) {
                     returnString = attrib.getAttributeType();
                 }
@@ -599,7 +615,7 @@
             returnString = parser.getAttributePrefix(i);
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) lastNode, i);
+                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
                 if (attrib != null) {
                     OMNamespace nameSpace = attrib.getNamespace();
                     if (nameSpace != null) {
@@ -625,7 +641,7 @@
             returnString = parser.getAttributeLocalName(i);
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) lastNode, i);
+                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
                 if (attrib != null) {
                     returnString = attrib.getLocalName();
                 }
@@ -648,7 +664,7 @@
             returnString = parser.getAttributeNamespace(i);
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) lastNode, i);
+                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
                 if (attrib != null) {
                     OMNamespace nameSpace = attrib.getNamespace();
                     if (nameSpace != null) {
@@ -674,7 +690,7 @@
             returnQName = parser.getAttributeName(i);
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                returnQName = getAttribute((OMElement) lastNode, i).getQName();
+                returnQName = getAttribute((OMElement) getNode(), i).getQName();
             } else {
                 throw new IllegalStateException(
                         "attribute count accessed in illegal event!");
@@ -693,7 +709,7 @@
             returnCount = parser.getAttributeCount();
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMElement elt = (OMElement) lastNode;
+                OMElement elt = (OMElement) getNode();
                 returnCount = getCount(elt.getAllAttributes());
             } else {
                 throw new IllegalStateException(
@@ -720,7 +736,7 @@
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
                 QName qname = new QName(s, s1);
-                OMAttribute attrib = ((OMElement) lastNode).getAttribute(qname);
+                OMAttribute attrib = ((OMElement) getNode()).getAttribute(qname);
                 if (attrib != null) {
                     returnString = attrib.getAttributeValue();
                 }
@@ -981,6 +997,7 @@
                 updateCompleteStatus();
                 break;
             case NAVIGABLE:
+                
                 currentEvent = generateEvents(currentNode);
                 updateCompleteStatus();
                 updateLastNode();
@@ -1009,14 +1026,14 @@
             return Boolean.TRUE;
         }
         if (OMConstants.IS_BINARY.equals(s)) {
-            if (lastNode instanceof OMText) {
-                OMText text = (OMText) lastNode;
+            if (getNode() instanceof OMText) {
+                OMText text = (OMText) getNode();
                 return new Boolean(text.isBinary());
             }
             return Boolean.FALSE;
         } else if (OMConstants.DATA_HANDLER.equals(s)) {
-            if (lastNode instanceof OMText) {
-                OMText text = (OMText) lastNode;    
+            if (getNode() instanceof OMText) {
+                OMText text = (OMText) getNode();    
                 if (text.isBinary())
                     return text.getDataHandler();
             }
@@ -1055,6 +1072,15 @@
      * @throws XMLStreamException
      */
     private void updateLastNode() throws XMLStreamException {
+        // Detect XOP:Include element and don't advance if processing
+        // the end tag.
+        if (xopInclude != null && 
+            xopIncludeText == currentNode &&
+            xopIncludeStart) {
+            lastNode = xopIncludeText;
+            return;
+        }  
+        
         lastNode = currentNode;
         currentNode = nextNode;
         try {
@@ -1139,7 +1165,12 @@
         if (state==SWITCHED){
             return parser.getNamespaceContext();
         }
-        return new NamespaceContextImpl(getAllNamespaces(lastNode));
+        Map m = getAllNamespaces(getNode());
+        if (getNode() != lastNode) {
+            // Handle situation involving substituted node.
+            m.putAll(getAllNamespaces(lastNode));
+        }
+        return new NamespaceContextImpl(m);
     }
 
     /**
@@ -1241,7 +1272,7 @@
                 returnEvent = generateElementEvents(element);
                 break;
             case OMNode.TEXT_NODE:
-                returnEvent = generateTextEvents();
+                returnEvent = generateTextEvents(node);
                 break;
             case OMNode.COMMENT_NODE:
                 returnEvent = generateCommentEvents();
@@ -1262,15 +1293,15 @@
      * @return Returns int.
      */
     private int generateElementEvents(OMElement elt) {
-        if (elementStack == null) {
-            elementStack = new Stack();
+        if (nodeStack == null) {
+            nodeStack = new Stack();
         }
         int returnValue = START_ELEMENT;
-        if (!elementStack.isEmpty() && elementStack.peek().equals(elt)) {
+        if (!nodeStack.isEmpty() && nodeStack.peek().equals(elt)) {
             returnValue = END_ELEMENT;
-            elementStack.pop();
+            nodeStack.pop();
         } else {
-            elementStack.push(elt);
+            nodeStack.push(elt);
         }
         return returnValue;
     }
@@ -1280,9 +1311,52 @@
      *
      * @return Returns int.
      */
-    private int generateTextEvents() {
+    private int generateTextEvents(OMNode node) {
+        if (!isInlineMTOM()) {
+            // If this is an optimized MTOM text node
+            // then simulate an XOP_INCLUDE element.
+            if (node instanceof OMText) {
+                OMText text = (OMText) node;
+                if (text.isOptimized()) {
+                    
+                    if (nodeStack == null) {
+                        nodeStack = new Stack();
+                    }
+                    
+                    if (!nodeStack.isEmpty() && nodeStack.peek().equals(text)) {
+                        // Process the end tag of the XOP:Include
+                        nodeStack.pop();
+                        xopIncludeStart = false;
+                        return END_ELEMENT;
+                    } else {
+
+                        // Create an XOPInclude element to represent this node
+                        xopIncludeText = text;
+                        xopInclude = node.getOMFactory().createOMElement(XOP_INCLUDE);
+                        String cid = text.getContentID();
+                        xopInclude.addAttribute("href", "cid:" + cid, null);
+                        xopIncludeStart = true;
+                        nodeStack.push(text);
+                        return START_ELEMENT;
+                    }
+                }
+            }
+        }
         return CHARACTERS;
     }
+    
+    /**
+     * @return the node to use for the current event
+     */
+    private OMNode getNode() {
+        // This method returns the node used to construct
+        // the current event (lastNode).  
+        // In some cases a new node is substitued (i.e. an XOPInclude element)
+        if (lastNode == xopIncludeText) {
+            return xopInclude;
+        }
+        return lastNode;
+    }
 
     /**
      * Method generateCommentEvents
@@ -1395,7 +1469,7 @@
         this.parser = parser;
     }
 
-    private Map getAllNamespaces(Object contextNode) {
+    private Map getAllNamespaces(OMNode contextNode) {
         if (!(contextNode instanceof OMContainer &&
                 contextNode instanceof OMElement)) {
             return new HashMap();
@@ -1472,10 +1546,32 @@
 
     public DataHandler getDataHandler(String blobcid) {
         DataHandler dh = null;
+        // The datahandler may be part of the attachments map of the builder
         if (builder != null && 
                 builder instanceof OMAttachmentAccessor) {
             dh = ((OMAttachmentAccessor) builder).getDataHandler(blobcid);
+        } 
+        
+        // Or the datahandler might be part of the current optimized text node
+        if (dh == null &&
+            lastNode != null && 
+            lastNode instanceof OMText) {
+            OMText text = (OMText) lastNode;
+            if (text.isOptimized() &&
+                    blobcid.equals("cid:" + text.getContentID())) {
+               dh = (DataHandler) text.getDataHandler();
+            }
         }
+                
         return dh;
     }
+
+    public boolean isInlineMTOM() {
+        return inlineMTOM;
+       
+    }
+
+    public void setInlineMTOM(boolean value) {
+        inlineMTOM = value;  
+    }
 }

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/mtom/MTOMStAXSOAPModelBuilderTest.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/mtom/MTOMStAXSOAPModelBuilderTest.java?rev=655845&r1=655844&r2=655845&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/mtom/MTOMStAXSOAPModelBuilderTest.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/mtom/MTOMStAXSOAPModelBuilderTest.java Tue May 13 05:56:37 2008
@@ -21,14 +21,17 @@
 
 import org.apache.axiom.attachments.Attachments;
 import org.apache.axiom.om.AbstractTestCase;
+import org.apache.axiom.om.OMAttachmentAccessor;
 import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.OMOutputFormat;
 import org.apache.axiom.om.OMText;
 import org.apache.axiom.om.OMXMLParserWrapper;
+import org.apache.axiom.om.OMXMLStreamReader;
 import org.apache.axiom.soap.SOAP12Constants;
 import org.apache.axiom.soap.impl.builder.MTOMStAXSOAPModelBuilder;
 
 import javax.activation.DataHandler;
+import javax.xml.namespace.QName;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamReader;
 
@@ -44,6 +47,9 @@
 
 public class MTOMStAXSOAPModelBuilderTest extends AbstractTestCase {
 
+    private final static QName XOP_INCLUDE = 
+        new QName("http://www.w3.org/2004/08/xop/include", "Include");
+    
     /** @param testName  */
     public MTOMStAXSOAPModelBuilderTest(String testName) {
         super(testName);
@@ -113,6 +119,7 @@
         assertTrue(msg.indexOf("Content-ID: <cid:-1609420109260943731>") > 0);
     }
     
+    
     public void testCreateAndSerializeInlined() throws Exception {
         String contentTypeString =
                 "multipart/Related; charset=\"UTF-8\"; type=\"application/xop+xml\"; boundary=\"----=_AxIs2_Def_boundary_=42214532\"; start=\"SOAPPart\"";
@@ -172,6 +179,54 @@
         System.out.println(root.toString());
     }
 
+    public void testCreateAndXMLStreamReader() throws Exception {
+        String contentTypeString =
+                "multipart/Related; charset=\"UTF-8\"; type=\"application/xop+xml\"; boundary=\"----=_AxIs2_Def_boundary_=42214532\"; start=\"SOAPPart\"";
+        String inFileName = "mtom/MTOMBuilderTestIn.txt";
+        InputStream inStream = new FileInputStream(getTestResourceFile(inFileName));
+        Attachments attachments = new Attachments(inStream, contentTypeString);
+        XMLStreamReader reader = XMLInputFactory.newInstance()
+                .createXMLStreamReader(new BufferedReader(new InputStreamReader(attachments
+                        .getSOAPPartInputStream())));
+        OMXMLParserWrapper builder = new MTOMStAXSOAPModelBuilder(reader, attachments,
+                                               SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
+        OMElement root = builder.getDocumentElement();
+        
+        // Build tree
+        root.build();
+        
+        // Use tree as input to XMLStreamReader
+        OMXMLStreamReader xmlStreamReader = (OMXMLStreamReader) root.getXMLStreamReader();
+        
+        // Issue XOP:Include events for optimized MTOM text nodes
+        xmlStreamReader.setInlineMTOM(false);
+        
+        DataHandler dh = null;
+        while(xmlStreamReader.hasNext() && dh == null) {
+            xmlStreamReader.next();
+            if (xmlStreamReader.isStartElement()) {
+                QName qName =xmlStreamReader.getName();
+                if (XOP_INCLUDE.equals(qName)) {
+                    String hrefValue = xmlStreamReader.getAttributeValue("", "href");
+                    if (hrefValue != null) {
+                        dh =((OMAttachmentAccessor)xmlStreamReader).getDataHandler(hrefValue);
+                    }
+                }
+            }
+        }
+        assertTrue(dh != null);   
+        
+        // Make sure next event is an an XOP_Include END element
+        xmlStreamReader.next();
+        assertTrue(xmlStreamReader.isEndElement());
+        assertTrue(XOP_INCLUDE.equals(xmlStreamReader.getName()));
+        
+        // Make sure the next event is the end tag of name
+        xmlStreamReader.next();
+        assertTrue(xmlStreamReader.isEndElement());
+        assertTrue("name".equals(xmlStreamReader.getLocalName()));
+    }
+   
     private byte[] append(byte[] a, byte[] b) {
         byte[] z = new byte[a.length + b.length];
         System.arraycopy(a, 0, z, 0, a.length);