ws-commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From veit...@apache.org
Subject svn commit: r793345 - in /webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom: om/impl/OMStAXWrapper.java om/impl/SwitchingWrapper.java util/stax/xop/XOPEncodingStreamReader.java
Date Sun, 12 Jul 2009 13:26:20 GMT
Author: veithen
Date: Sun Jul 12 13:26:19 2009
New Revision: 793345

URL: http://svn.apache.org/viewvc?rev=793345&view=rev
Log:
WSCOMMONS-488: Make sure that when inlineMTOM is set to false, OMStAXWrapper always produces xop:Include elements, even if the underlying stream is not XOP/MTOM (but uses the data handler extension).

Changes:
* Reverted the change in r655845 related to WSCOMMONS-344.
* Refactored OMStAXWrapper to use a facade/delegate pattern:
  - When inlineMTOM is set to true (default), it delegates directly to SwitchingWrapper (new class which contains the major part of the code in the old OMStAXWrapper).
  - When inlineMTOM is set to false, OMStAXWrapper inserts an XOPEncodingStreamReader between itself and the SwitchingWrapper. This will generate the xop:Include elements.
* Some fixes in XOPEncodingStreamReader.

Tested the change with Axis2.

Added:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/SwitchingWrapper.java
      - copied, changed from r793246, webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/OMStAXWrapper.java
Modified:
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/OMStAXWrapper.java
    webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java

Modified: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/OMStAXWrapper.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/OMStAXWrapper.java?rev=793345&r1=793344&r2=793345&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/OMStAXWrapper.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/OMStAXWrapper.java Sun Jul 12 13:26:19 2009
@@ -19,184 +19,42 @@
 
 package org.apache.axiom.om.impl;
 
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Stack;
-
 import javax.activation.DataHandler;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.namespace.QName;
-import javax.xml.stream.Location;
-import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.util.StreamReaderDelegate;
 
-import org.apache.axiom.ext.stax.datahandler.DataHandlerProvider;
-import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
 import org.apache.axiom.om.OMAttachmentAccessor;
-import org.apache.axiom.om.OMAttribute;
-import org.apache.axiom.om.OMComment;
-import org.apache.axiom.om.OMContainer;
-import org.apache.axiom.om.OMDocument;
 import org.apache.axiom.om.OMElement;
-import org.apache.axiom.om.OMNamespace;
-import org.apache.axiom.om.OMNode;
-import org.apache.axiom.om.OMProcessingInstruction;
-import org.apache.axiom.om.OMSourcedElement;
-import org.apache.axiom.om.OMText;
+import org.apache.axiom.om.OMException;
 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.OMNavigator;
-import org.apache.axiom.om.impl.builder.DataHandlerReaderUtil;
-import org.apache.axiom.om.impl.builder.StAXBuilder;
-import org.apache.axiom.om.impl.exception.OMStreamingException;
-import org.apache.axiom.om.impl.util.NamespaceContextImpl;
-import org.apache.axiom.util.stax.AbstractXMLStreamReader;
+import org.apache.axiom.om.util.UUIDGenerator;
+import org.apache.axiom.util.stax.xop.ContentIDGenerator;
+import org.apache.axiom.util.stax.xop.XOPEncodingStreamReader;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 /**
- * Note - This class also implements the streaming constants interface to get access to the StAX
- * constants.
+ * {@link XMLStreamReader} implementation that generates events from a given Axiom tree.
  */
-public class OMStAXWrapper extends AbstractXMLStreamReader
-    implements OMXMLStreamReader, DataHandlerReader, XMLStreamConstants {
-    
+public class OMStAXWrapper extends StreamReaderDelegate implements OMXMLStreamReader {
     private static final Log log = LogFactory.getLog(OMStAXWrapper.class);
-    private static boolean DEBUG_ENABLED = log.isDebugEnabled();
-    
-    /** Field navigator */
-    private OMNavigator navigator;
-
-    /** Field builder */
-    private OMXMLParserWrapper builder;
-
-    /** Field parser */
-    private XMLStreamReader parser;
-    
-    /**
-     * The {@link DataHandlerReader} extension of the underlying parser, or <code>null</code>
-     * if the parser doesn't support this extension.
-     */
-    private DataHandlerReader dataHandlerReader;
-    
-    private boolean _isClosed = false;              // Indicate if parser is closed
-    private boolean _releaseParserOnClose = false;  // Defaults to legacy behavior, which is keep the reference
-
-    /** Field rootNode */
-    private OMNode rootNode;
-
-    /** Field isFirst */
-    private boolean isFirst = true;
-
-    // Navigable means the output should be taken from the navigator.
-    // As soon as the navigator returns a null navigable will be reset
-    // to false and the subsequent events will be taken from the builder
-    // or the parser directly.
-
-    /** Field NAVIGABLE */
-    private static final short NAVIGABLE = 0;
-    private static final short SWITCH_AT_NEXT = 1;
-    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 */
-    private short state;
-
-    /** Field currentEvent Default set to START_DOCUMENT */
-    private int currentEvent = START_DOCUMENT;
-
-    // SwitchingAllowed is set to false by default.
-    // This means that unless the user explicitly states
-    // that he wants things not to be cached, everything will
-    // be cached.
-
-    /** Field switchingAllowed */
-    boolean switchingAllowed = false;
-    
-    // namespaceURI interning
-    // default is false because most XMLStreamReader implementations don't do interning
-    // due to performance impacts
-    boolean namespaceURIInterning = false;
-
-    /** Field elementStack */
-    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
-    // returns a null
-
-    /** Field nextNode */
-    private OMNode nextNode = null;
-
-    // holder for the current node. Needs this to generate events from the
-    // current node
-
-    /** Field currentNode */
-    private OMNode currentNode = null;
-
-    // needs this to refer to the last known node
-
-    /** Field lastNode */
-    private OMNode lastNode = null;
-
-    /** Track depth to ensure we stop generating events when we are done with the root node. */
-    int depth = 0;
-
-    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.
-     *
-     * @param b
-     */
-    public void setAllowSwitching(boolean b) {
-        this.switchingAllowed = b;
-    }
-
-    /**
-     * Method isAllowSwitching.
-     *
-     * @return Returns boolean.
-     */
-    public boolean isAllowSwitching() {
-        return switchingAllowed;
-    }
-
-    /**
-     * Set namespace uri interning
-     * @param b
-     */
-    public void setNamespaceURIInterning(boolean b) {
-        this.namespaceURIInterning = b;
-    }
     
-    /**
-     * @return if namespace uri interning 
-     */
-    public boolean isNamespaceURIInterning() {
-        return this.namespaceURIInterning;
-    }
+    private static final ContentIDGenerator contentIDGenerator = new ContentIDGenerator() {
+        public String generateContentID(String existingContentID) {
+            if (existingContentID == null) {
+                // TODO: This is what we do in OMTextImpl#getContentID(); note that this doesn't
+                //       generate a content ID that strictly conforms to the specs
+                return UUIDGenerator.getUUID() + "@apache.org";
+            } else {
+                return existingContentID;
+            }
+        }
+    };
     
+    private final SwitchingWrapper switchingWrapper;
+    private XOPEncodingStreamReader xopEncoder;
     
     /**
      * When constructing the OMStaxWrapper, the creator must produce the builder (an instance of the
@@ -220,1444 +78,90 @@
      */
     public OMStAXWrapper(OMXMLParserWrapper builder, OMElement startNode,
                          boolean cache) {
-
-        // create a navigator
-        this.navigator = new OMNavigator(startNode);
-        this.builder = builder;
-        this.rootNode = startNode;
-        if (rootNode != null && rootNode.getParent() != null &&
-                rootNode.getParent() instanceof OMDocument) {
-            needToThrowEndDocument = true;
-        }
-
-        // initiate the next and current nodes
-        // Note - navigator is written in such a way that it first
-        // returns the starting node at the first call to it
-        // Note - for OMSourcedElements, temporarily set caching
-        // to get the initial navigator nodes
-        boolean resetCache = false;
-        try {
-            if (startNode instanceof OMSourcedElement && 
-                    !cache && builder != null) {
-                if (!builder.isCache()) {
-                    resetCache = true;
-                }
-                builder.setCache(true); // bootstrap the navigator
-                
-            }
-        } catch(Throwable t) {}
-        
-        currentNode = navigator.next();
-        updateNextNode();
-        if (resetCache) {
-            builder.setCache(cache); 
-        }
-        switchingAllowed = !cache;
-    }
-
-    /**
-     * @return Returns String.
-     * @see javax.xml.stream.XMLStreamReader#getPrefix()
-     */
-    public String getPrefix() {
-        if (parser != null) {
-            return parser.getPrefix();
-        } else {
-            if ((currentEvent == START_ELEMENT)
-                    || (currentEvent == END_ELEMENT)) {
-                OMNamespace ns = ((OMElement) getNode()).getNamespace();
-                if (ns == null) {
-                    return null;
-                } else {
-                    String prefix = ns.getPrefix();
-                    return prefix == null || prefix.length() == 0 ? null : prefix; 
-                }
-            } else {
-                throw new IllegalStateException();
-            }
-        }
-    }
-
-    /**
-     * @return Returns String.
-     * @see javax.xml.stream.XMLStreamReader#getNamespaceURI()
-     */
-    public String getNamespaceURI() {
-        String returnStr;
-        if (parser != null) {
-            returnStr = parser.getNamespaceURI();
-        } else {
-            if ((currentEvent == START_ELEMENT)
-                    || (currentEvent == END_ELEMENT)
-                    || (currentEvent == NAMESPACE)) {
-                OMNamespace ns = ((OMElement) getNode()).getNamespace();
-                if (ns == null) {
-                    returnStr = null;
-                } else {
-                    String namespaceURI = ns.getNamespaceURI();
-                    returnStr = namespaceURI.length() == 0 ? null : namespaceURI;
-                }
-            } else {
-                throw new IllegalStateException();
-            }
-        }
-        
-        // By default most parsers don't intern the namespace.
-        // Unfortunately the property to detect interning on the delegate parsers is hard to detect.
-        // Woodstox has a proprietary property on the XMLInputFactory.
-        // IBM has a proprietary property on the XMLStreamReader.
-        // For now only force the interning if requested.
-        if (this.isNamespaceURIInterning()) {
-            returnStr = (returnStr != null) ? returnStr.intern() : null;
-        }
-        return returnStr;
+        switchingWrapper = new SwitchingWrapper(builder, startNode, cache);
+        setParent(switchingWrapper);
     }
 
-    /**
-     * @return Returns boolean.
-     * @see javax.xml.stream.XMLStreamReader#hasName()
-     */
-    public boolean hasName() {
-        if (parser != null) {
-            return parser.hasName();
-        } else {
-            return ((currentEvent == START_ELEMENT)
-                    || (currentEvent == END_ELEMENT));
-        }
+    public boolean isInlineMTOM() {
+        return xopEncoder == null;
     }
 
-    /**
-     * @return Returns String.
-     * @see javax.xml.stream.XMLStreamReader#getLocalName()
-     */
-    public String getLocalName() {
-        if (parser != null) {
-            return parser.getLocalName();
-        } else {
-            if ((currentEvent == START_ELEMENT)
-                    || (currentEvent == END_ELEMENT)
-                    || (currentEvent == ENTITY_REFERENCE)) {
-                return ((OMElement) getNode()).getLocalName();
-            } else {
-                throw new IllegalStateException();
+    public void setInlineMTOM(boolean value) {
+        // For inlineMTOM=false, we insert an XOPEncodingStreamReader proxy between
+        // us and SwitchingWrapper.
+        // For inlineMTOM=true, we remove it and delegate directly to SwitchingWrapper.
+        if (value) {
+            if (xopEncoder != null) {
+                xopEncoder = null;
+                setParent(switchingWrapper);
             }
-        }
-    }
-
-    /**
-     * @return Returns QName.
-     * @see javax.xml.stream.XMLStreamReader#getName()
-     */
-    public QName getName() {
-        if (parser != null) {
-            return parser.getName();
         } else {
-            if ((currentEvent == START_ELEMENT)
-                    || (currentEvent == END_ELEMENT)) {
-                return getQName((OMElement) getNode());
-            } else {
-                throw new IllegalStateException();
+            if (xopEncoder == null) {
+                xopEncoder = new XOPEncodingStreamReader(switchingWrapper, contentIDGenerator);
+                setParent(xopEncoder);
             }
         }
     }
 
-    /**
-     * @return Returns int.
-     * @see javax.xml.stream.XMLStreamReader#getTextLength()
-     */
-    public int getTextLength() {
-        if (parser != null) {
-            return parser.getTextLength();
-        } else {
-            return getTextFromNode().length();
+    public DataHandler getDataHandler(String contentID) {
+        if (contentID.startsWith("cid:")) {
+            log.warn("Invalid usage of OMStAXWrapper#getDataHandler(String): the argument must " +
+            		"be a content ID, not an href; see OMAttachmentAccessor.");
+            contentID = contentID.substring(4);
         }
-    }
-
-    /**
-     * @return Returns int.
-     * @see javax.xml.stream.XMLStreamReader#getTextStart()
-     */
-    public int getTextStart() {
-        if (parser != null) {
-            return parser.getTextStart();
-        } else {
-            if (hasText()) {
-                // getTextCharacters always returns a new char array and the start
-                // index is therefore always 0
-                return 0;
-            } else {
-                throw new IllegalStateException();
+        
+        // Temporary workaround for WSCOMMONS-485:
+        OMXMLParserWrapper builder = switchingWrapper.getBuilder();
+        if (builder != null && 
+                builder instanceof OMAttachmentAccessor) {
+            DataHandler dh = ((OMAttachmentAccessor)builder).getDataHandler(contentID);
+            if (dh != null) {
+                return dh;
             }
+        } 
+        
+        if (xopEncoder == null) {
+            throw new IllegalStateException("The wrapper is in inlineMTOM=true mode");
         }
-    }
-
-    /**
-     * @param sourceStart
-     * @param target
-     * @param targetStart
-     * @param length
-     * @return Returns int.
-     * @throws XMLStreamException
-     * @see javax.xml.stream.XMLStreamReader#getTextCharacters(int, char[], int, int)
-     */
-    public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
-            throws XMLStreamException {
-        if (parser != null) {
+        if (xopEncoder.getContentIDs().contains(contentID)) {
             try {
-                return parser.getTextCharacters(sourceStart, target, targetStart, length);
-            } catch (XMLStreamException e) {
-                throw new OMStreamingException(e);
+                return xopEncoder.getDataHandler(contentID);
+            } catch (XMLStreamException ex) {
+                throw new OMException(ex);
             }
         } else {
-            String text = getTextFromNode();
-            int copied = Math.min(length, text.length()-sourceStart);
-            text.getChars(sourceStart, sourceStart + copied, target, targetStart);
-            return copied;
-        }
-    }
-
-    /**
-     * @return Returns char[].
-     * @see javax.xml.stream.XMLStreamReader#getTextCharacters()
-     */
-    public char[] getTextCharacters() {
-        if (parser != null) {
-            return parser.getTextCharacters();
-        } else {
-            return getTextFromNode().toCharArray();
-        }
-    }
-
-    /**
-     * @return Returns String.
-     * @see javax.xml.stream.XMLStreamReader#getText()
-     */
-    public String getText() {
-        if (parser != null) {
-            return parser.getText();
-        } else {
-            return getTextFromNode();
+            return null;
         }
     }
     
-    private String getTextFromNode() {
-        switch (currentEvent) {
-            case CHARACTERS:
-            case CDATA:
-            case SPACE:
-                return ((OMText)getNode()).getText();
-            case COMMENT:
-                return ((OMComment)getNode()).getValue();
-            default:
-                throw new IllegalStateException();
-        }
-    }
-
-    /**
-     * @return Returns int.
-     * @see javax.xml.stream.XMLStreamReader#getEventType()
-     */
-
-    // todo this should be improved
-    public int getEventType() {
-        return currentEvent;
-    }
-
-    /**
-     * @param i
-     * @return Returns String.
-     * @see javax.xml.stream.XMLStreamReader#getNamespaceURI
-     */
-    public String getNamespaceURI(int i) {
-        String returnString = null;
-        if (parser != null) {
-            returnString = parser.getNamespaceURI(i);
-        } else {
-            if (isStartElement() || isEndElement()
-                    || (currentEvent == NAMESPACE)) {
-                OMNamespace ns = (OMNamespace) getItemFromIterator(
-                        ((OMElement) getNode()).getAllDeclaredNamespaces(), i);
-                returnString = (ns == null) ? null : ns.getNamespaceURI();
-            }
-        }
-
-        /*
-          The following line is necessary to overcome an issue where the empty
-          namespace URI returning null rather than the empty string. Our resolution
-          is to return "" if the return is actually null
-
-          Note that this is not the case for  getNamespaceURI(prefix) method
-          where the contract clearly specifies that the return may be null
-
-        */
-        if (returnString == null) returnString = "";
-
-        return returnString;
-    }
-
-    /**
-     * @param i
-     * @return Returns String.
-     * @see javax.xml.stream.XMLStreamReader#getNamespacePrefix
-     */
-    public String getNamespacePrefix(int i) {
-        String returnString = null;
-        if (parser != null) {
-            returnString = parser.getNamespacePrefix(i);
-        } else {
-            if (isStartElement() || isEndElement()
-                    || (currentEvent == NAMESPACE)) {
-                OMNamespace ns = (OMNamespace) getItemFromIterator(
-                        ((OMElement) getNode()).getAllDeclaredNamespaces(), i);
-                if (ns != null) {
-                    String prefix = ns.getPrefix();
-                    returnString = prefix == null || prefix.length() == 0 ? null : prefix; 
-                }
-            }
-        }
-        return returnString;
-    }
-
-    /**
-     * @return Returns int.
-     * @see javax.xml.stream.XMLStreamReader#getNamespaceCount()
-     */
-    public int getNamespaceCount() {
-        if (parser != null) {
-            return parser.getNamespaceCount();
-        } else {
-            if (isStartElement() || isEndElement()
-                    || (currentEvent == NAMESPACE)) {
-                return getCount(((OMElement) getNode())
-                        .getAllDeclaredNamespaces());
-            } else {
-                throw new IllegalStateException();
-            }
-        }
-    }
-
-    /**
-     * @param i
-     * @return Returns boolean.
-     * @see javax.xml.stream.XMLStreamReader#isAttributeSpecified
-     */
-    public boolean isAttributeSpecified(int i) {
-        if (parser != null) {
-            return parser.isAttributeSpecified(i);
-        } else {
-            if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                // The Axiom object model doesn't store this information,
-                // but returning true is a reasonable default.
-                return true;
-            } else {
-                throw new IllegalStateException(
-                        "attribute type accessed in illegal event!");
-            }
-        }
-    }
-
-    /**
-     * @param i
-     * @return Returns String.
-     * @see javax.xml.stream.XMLStreamReader#getAttributeValue
-     */
-    public String getAttributeValue(int i) {
-        String returnString = null;
-        if (parser != null) {
-            returnString = parser.getAttributeValue(i);
-        } else {
-            if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
-                if (attrib != null) {
-                    returnString = attrib.getAttributeValue();
-                }
-            } else {
-                throw new IllegalStateException(
-                        "attribute type accessed in illegal event!");
-            }
-        }
-        return returnString;
-    }
-
-    /**
-     * @param i
-     * @return Returns String.
-     * @see javax.xml.stream.XMLStreamReader#getAttributeType
-     */
-    public String getAttributeType(int i) {
-        String returnString = null;
-        if (parser != null) {
-            returnString = parser.getAttributeType(i);
-        } else {
-            if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
-                if (attrib != null) {
-                    returnString = attrib.getAttributeType();
-                }
-
-            } else {
-                throw new IllegalStateException(
-                        "attribute type accessed in illegal event!");
-            }
-        }
-        return returnString;
-    }
-
-    /**
-     * @param i
-     * @return Returns String.
-     * @see javax.xml.stream.XMLStreamReader#getAttributePrefix
-     */
-    public String getAttributePrefix(int i) {
-        String returnString = null;
-        if (parser != null) {
-            returnString = parser.getAttributePrefix(i);
-        } else {
-            if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
-                if (attrib != null) {
-                    OMNamespace nameSpace = attrib.getNamespace();
-                    if (nameSpace != null) {
-                        returnString = nameSpace.getPrefix();
-                    }
-                }
-            } else {
-                throw new IllegalStateException(
-                        "attribute prefix accessed in illegal event!");
-            }
-        }
-        return returnString;
-    }
-
-    /**
-     * @param i
-     * @return Returns String.
-     * @see javax.xml.stream.XMLStreamReader#getAttributeLocalName
-     */
-    public String getAttributeLocalName(int i) {
-        String returnString = null;
-        if (parser != null) {
-            returnString = parser.getAttributeLocalName(i);
-        } else {
-            if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
-                if (attrib != null) {
-                    returnString = attrib.getLocalName();
-                }
-            } else {
-                throw new IllegalStateException(
-                        "attribute localName accessed in illegal event!");
-            }
-        }
-        return returnString;
-    }
-
-    /**
-     * @param i
-     * @return Returns String.
-     * @see javax.xml.stream.XMLStreamReader#getAttributeNamespace
-     */
-    public String getAttributeNamespace(int i) {
-        String returnString = null;
-        if (parser != null) {
-            returnString = parser.getAttributeNamespace(i);
-        } else {
-            if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
-                if (attrib != null) {
-                    OMNamespace nameSpace = attrib.getNamespace();
-                    if (nameSpace != null) {
-                        returnString = nameSpace.getNamespaceURI();
-                    }
-                }
-            } else {
-                throw new IllegalStateException(
-                        "attribute nameSpace accessed in illegal event!");
-            }
-        }
-        return returnString;
-    }
-
-    /**
-     * @param i
-     * @return Returns QName.
-     * @see javax.xml.stream.XMLStreamReader#getAttributeName
-     */
-    public QName getAttributeName(int i) {
-        QName returnQName = null;
-        if (parser != null) {
-            returnQName = parser.getAttributeName(i);
-        } else {
-            if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                returnQName = getAttribute((OMElement) getNode(), i).getQName();
-            } else {
-                throw new IllegalStateException(
-                        "attribute count accessed in illegal event!");
-            }
-        }
-        return returnQName;
+    // TODO: need to check which of these delegate methods are really necessary;
+    //       some of them should also be defined properly by an interface
+    
+    public OMXMLParserWrapper getBuilder() {
+        return switchingWrapper.getBuilder();
     }
 
-    /**
-     * @return Returns int.
-     * @see javax.xml.stream.XMLStreamReader#getAttributeCount
-     */
-    public int getAttributeCount() {
-        int returnCount = 0;
-        if (parser != null) {
-            returnCount = parser.getAttributeCount();
-        } else {
-            if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMElement elt = (OMElement) getNode();
-                returnCount = getCount(elt.getAllAttributes());
-            } else {
-                throw new IllegalStateException(
-                        "attribute count accessed in illegal event (" +
-                                currentEvent + ")!");
-            }
-        }
-        return returnCount;
+    public boolean isAllowSwitching() {
+        return switchingWrapper.isAllowSwitching();
     }
 
-    // todo
-
-    /**
-     * Method getAttributeValue.
-     *
-     * @param s
-     * @param s1
-     * @return Returns String.
-     */
-    public String getAttributeValue(String s, String s1) {
-        String returnString = null;
-        if (parser != null) {
-            returnString = parser.getAttributeValue(s, s1);
-        } else {
-            if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                QName qname = new QName(s, s1);
-                OMAttribute attrib = ((OMElement) getNode()).getAttribute(qname);
-                if (attrib != null) {
-                    returnString = attrib.getAttributeValue();
-                }
-            } else {
-                throw new IllegalStateException(
-                        "attribute type accessed in illegal event!");
-            }
-        }
-        return returnString;
+    public boolean isClosed() {
+        return switchingWrapper.isClosed();
     }
 
-    /**
-     * Method isWhiteSpace.
-     *
-     * @return Returns boolean.
-     */
-    public boolean isWhiteSpace() {
-        if (parser != null) {
-            return parser.isWhiteSpace();
-        } else {
-            switch (currentEvent) {
-                case SPACE:
-                    return true;
-                case CHARACTERS:
-                    // XMLStreamReader Javadoc says that isWhiteSpace "returns true if the cursor
-                    // points to a character data event that consists of all whitespace". This
-                    // means that this method may return true for a CHARACTER event and we need
-                    // to scan the text of the node.
-                    String text = getTextFromNode();
-                    for (int i=0; i<text.length(); i++) {
-                        char c = text.charAt(i);
-                        if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
-                            return false;
-                        }
-                    }
-                    return true;
-                default:
-                    return false;
-            }
-        }
+    public void releaseParserOnClose(boolean value) {
+        switchingWrapper.releaseParserOnClose(value);
     }
 
-    /**
-     * Method isCharacters.
-     *
-     * @return Returns boolean.
-     */
-    public boolean isCharacters() {
-        boolean b;
-        if (parser != null) {
-            b = parser.isCharacters();
-        } else {
-            b = (currentEvent == CHARACTERS);
-        }
-        return b;
+    public void setAllowSwitching(boolean b) {
+        switchingWrapper.setAllowSwitching(b);
     }
 
-    /**
-     * Method isEndElement.
-     *
-     * @return Returns boolean.
-     */
-    public boolean isEndElement() {
-        boolean b;
-        if (parser != null) {
-            b = parser.isEndElement();
-        } else {
-            b = (currentEvent == END_ELEMENT);
-        }
-        return b;
+    public void setParser(XMLStreamReader parser) {
+        switchingWrapper.setParser(parser);
     }
 
-    /**
-     * Method isStartElement.
-     *
-     * @return Returns boolean.
-     */
-    public boolean isStartElement() {
-        boolean b;
-        if (parser != null) {
-            b = parser.isStartElement();
-        } else {
-            b = (currentEvent == START_ELEMENT);
-        }
-        return b;
-    }
-
-    /**
-     * Method getNamespaceURI.
-     *
-     * @param prefix
-     * @return Returns String.
-     */
-    public String getNamespaceURI(String prefix) {
-        String returnString = null;
-        if (parser != null) {
-            returnString = parser.getNamespaceURI(prefix);
-        } else {
-            if (isStartElement() || isEndElement()
-                    || (currentEvent == NAMESPACE)) {
-
-                OMNode node = getNode();
-                if (node instanceof OMElement) {
-                    OMNamespace namespaceURI =
-                            ((OMElement) node).findNamespaceURI(prefix);
-                    return namespaceURI != null ? namespaceURI.getNamespaceURI() : null;
-                }
-            }
-        }
-        return returnString;
-    }
-
-    /**
-     * Method close.
-     *
-     * @throws XMLStreamException
-     */
-    public void close() throws XMLStreamException {
-
-        // If there is a builder, it controls its parser
-        if (builder != null && builder instanceof StAXBuilder) {
-            StAXBuilder staxBuilder = (StAXBuilder) builder;
-            staxBuilder.close();
-            setParser(null);
-        } else {
-            if (parser != null) {
-                try {
-                    if (!isClosed()) {
-                        parser.close();
-                    }
-                } finally {
-                    _isClosed = true;
-                    // Release the parser so that it can be GC'd or reused.
-                    if (_releaseParserOnClose) {
-                        setParser(null);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Method hasNext.
-     *
-     * @return Returns boolean.
-     * @throws XMLStreamException
-     */
-    public boolean hasNext() throws XMLStreamException {
-        if (needToThrowEndDocument) {
-            return !(state == DOCUMENT_COMPLETE);
-        } else {
-            return (state != COMPLETED && currentEvent != END_DOCUMENT);
-        }
-    }
-
-    /**
-     * @return Returns String.
-     * @throws XMLStreamException
-     * @see javax.xml.stream.XMLStreamReader#getElementText()
-     */
-    public String getElementText() throws XMLStreamException {
-        if (parser != null) {
-            try {
-                return parser.getElementText();
-            } catch (XMLStreamException e) {
-                throw new OMStreamingException(e);
-            }
-        } else {
-            ///////////////////////////////////////////////////////
-            //// Code block directly from the API documentation ///
-            if (getEventType() != XMLStreamConstants.START_ELEMENT) {
-                throw new XMLStreamException(
-                        "parser must be on START_ELEMENT to read next text", getLocation());
-            }
-            int eventType = next();
-            StringBuffer content = new StringBuffer();
-            while (eventType != XMLStreamConstants.END_ELEMENT) {
-                if (eventType == XMLStreamConstants.CHARACTERS
-                        || eventType == XMLStreamConstants.CDATA
-                        || eventType == XMLStreamConstants.SPACE
-                        || eventType == XMLStreamConstants.ENTITY_REFERENCE) {
-                    content.append(getText());
-                } else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
-                        || eventType == XMLStreamConstants.COMMENT) {
-                    // skipping
-                } else if (eventType == XMLStreamConstants.END_DOCUMENT) {
-                    throw new XMLStreamException(
-                            "unexpected end of document when reading element text content");
-                } else if (eventType == XMLStreamConstants.START_ELEMENT) {
-                    throw new XMLStreamException(
-                            "element text content may not contain START_ELEMENT");
-                } else {
-                    throw new XMLStreamException(
-                            "Unexpected event type " + eventType, getLocation());
-                }
-                eventType = next();
-            }
-            return content.toString();
-            ///////////////////////////////////////////////////////////////
-        }
-
-    }
-
-    /**
-     * Method next.
-     *
-     * @return Returns int.
-     * @throws XMLStreamException
-     */
-    public int next() throws XMLStreamException {
-        switch (state) {
-            case DOCUMENT_COMPLETE:
-                throw new NoSuchElementException("End of the document reached");
-            case COMPLETED:
-                state = DOCUMENT_COMPLETE;
-                currentEvent = END_DOCUMENT;
-                break;
-            case SWITCH_AT_NEXT:
-                state = SWITCHED;
-
-                // load the parser
-                try {
-                    setParser((XMLStreamReader) builder.getParser());
-                } catch (Exception e) {
-                    throw new XMLStreamException("problem accessing the parser. " + e.getMessage(),
-                                                 e);
-                }
-
-                // We should throw an END_DOCUMENT
-                if ((currentEvent == START_DOCUMENT)
-                        && (currentEvent == parser.getEventType())) {
-                    currentEvent = parser.next();
-                } else {
-                    currentEvent = parser.getEventType();
-                }
-                updateCompleteStatus();
-                break;
-            case NAVIGABLE:
-                currentEvent = generateEvents(currentNode);
-                updateCompleteStatus();
-                updateLastNode();
-                break;
-            case SWITCHED:
-                if (parser.hasNext()) {
-                    currentEvent = parser.next();
-                }
-                updateCompleteStatus();
-                break;
-            default:
-                throw new OMStreamingException("unsuppported state!");
-        }
-        return currentEvent;
-    }
-
-    /**
-     * Method getProperty.
-     *
-     * @param s
-     * @return Returns Object.
-     * @throws IllegalArgumentException
-     */
-    public Object getProperty(String s) throws IllegalArgumentException {
-        Object value = DataHandlerReaderUtil.processGetProperty(this, s);
-        if (value != null) {
-            return value;
-        }
-        if (parser != null) {
-            return parser.getProperty(s);
-        }
-        // Delegate to the builder's parser.
-        if (builder != null && builder instanceof StAXBuilder) {
-            StAXBuilder staxBuilder = (StAXBuilder) builder;
-            if (!staxBuilder.isClosed()) {
-                // If the parser was closed by something other
-                // than the builder, an IllegalStateException is
-                // thrown.  For now, return null as this is unexpected
-                // by the caller.
-                try {
-                    return ((StAXBuilder) builder).getReaderProperty(s);
-                } catch (IllegalStateException ise) {
-                    return null;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * This is a very important method. It keeps the navigator one step ahead and pushes it one
-     * event ahead. If the nextNode is null then navigable is set to false. At the same time the
-     * parser and builder are set up for the upcoming event generation.
-     *
-     * @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 {
-            updateNextNode();
-        } catch (Exception e) {
-            throw new XMLStreamException(e);
-        }
-    }
-
-    /** Method updateNextNode. */
-    private void updateNextNode() {
-        if (navigator.isNavigable()) {
-            nextNode = navigator.next();
-        } else {
-            if (!switchingAllowed) {
-                if (navigator.isCompleted() || builder == null || builder.isCompleted()) {
-                    nextNode = null;
-                    if (DEBUG_ENABLED) {
-                        if (builder == null || builder.isCompleted()) {
-                            log.debug("Builder is complete.  Next node is set to null.");
-                        }
-                    }
-                } else {
-                    builder.next();
-                    navigator.step();
-                    nextNode = navigator.next();
-                }
-            } else {
-                //at this point check whether the navigator is done
-                //if the navigator is done then we are fine and can directly
-                // jump to the complete state ?
-                if (navigator.isCompleted()) {
-                    nextNode = null;
-                } else {
-                    // reset caching (the default is ON so it was not needed in the
-                    // earlier case!
-                    if (builder != null) {
-                        builder.setCache(false);
-                    }
-                    state = SWITCH_AT_NEXT;
-                }
-            }
-        }
-    }
-
-    /** Method updateCompleteStatus. */
-    private void updateCompleteStatus() {
-        if (state == NAVIGABLE) {
-            if (rootNode == currentNode) {
-                if (isFirst) {
-                    isFirst = false;
-                } else {
-                    state = COMPLETED;
-                }
-            }
-        } else {
-            if (state == SWITCHED) {
-                //this is a potential place for bugs
-                //we have to test if the root node of this parser
-                //has the same name for this test
-                if (currentEvent == START_ELEMENT &&
-                        (parser.getLocalName().equals(((OMElement)rootNode).getLocalName()))) {
-                    ++depth;
-                } else if (currentEvent == END_ELEMENT   &&
-                       (parser.getLocalName().equals(((OMElement)rootNode).getLocalName())) ) {                                      
-                    --depth;
-                    if (depth < 0) {
-                        state = COMPLETED;
-                    }
-                }
-            }
-            state = (currentEvent == END_DOCUMENT)
-                    ? DOCUMENT_COMPLETE
-                    : state;
-        }
-    }
-
-    /**
-     * Method getNamespaceContext.
-     *
-     * @return Returns NamespaceContext.
-     */
-    public NamespaceContext getNamespaceContext() {
-        if (state==SWITCHED){
-            return parser.getNamespaceContext();
-        }
-        Map m;
-        if (currentEvent == END_DOCUMENT) {
-            m = Collections.EMPTY_MAP;
-        } else {
-            m = getAllNamespaces(getNode());
-            if (getNode() != lastNode) {
-                // Handle situation involving substituted node.
-                m.putAll(getAllNamespaces(lastNode));
-            }
-        }
-        return new NamespaceContextImpl(m);
-    }
-
-    /**
-     * Method getEncoding.
-     *
-     * @return Returns String.
-     */
-    public String getEncoding() {
-        return null;
-    }
-
-    /**
-     * Method getLocation.
-     *
-     * @return Returns Location.
-     */
-    public Location getLocation() {
-        return new EmptyOMLocation();
-    }
-
-    /**
-     * Method getVersion.
-     *
-     * @return Returns String.
-     */
-    public String getVersion() {
-        return "1.0"; // todo put the constant
-    }
-
-    /**
-     * Method isStandalone.
-     *
-     * @return Returns boolean.
-     */
-    public boolean isStandalone() {
-        return true;
-    }
-
-    /**
-     * Method standaloneSet.
-     *
-     * @return Returns boolean.
-     */
-    public boolean standaloneSet() {
-        return false;
-    }
-
-    /**
-     * Method getCharacterEncodingScheme.
-     *
-     * @return Returns String.
-     */
-    public String getCharacterEncodingScheme() {
-        if(builder != null) {
-            return builder.getCharacterEncoding();
-        }
-        return "utf-8";
-    }
-
-    /**
-     * Method getPITarget.
-     *
-     * @return Returns String.
-     */
-    public String getPITarget() {
-        if (parser != null) {
-            return parser.getPIData();
-        } else {
-            if (currentEvent == PROCESSING_INSTRUCTION) {
-                return ((OMProcessingInstruction)getNode()).getTarget();
-            } else {
-                throw new IllegalStateException();
-            }
-        }
-    }
-
-    /**
-     * Method getPIData.
-     *
-     * @return Returns String.
-     */
-    public String getPIData() {
-        if (parser != null) {
-            return parser.getPIData();
-        } else {
-            if (currentEvent == PROCESSING_INSTRUCTION) {
-                return ((OMProcessingInstruction)getNode()).getValue();
-            } else {
-                throw new IllegalStateException();
-            }
-        }
-    }
-
-    /*
-     *
-     * ################################################################
-     * DataHandlerReader extension methods
-     * ################################################################
-     *
-     */
-
-    public boolean isBinary() {
-        if (parser != null) {
-            if (dataHandlerReader != null) {
-                return dataHandlerReader.isBinary();
-            } else {
-                return false;
-            }
-        } else {
-            OMNode node = getNode();
-            if (node instanceof OMText) {
-                return ((OMText)node).isBinary();
-            } else {
-                return false;
-            }
-        }
-    }
-
-    public boolean isDeferred() {
-        if (parser != null) {
-            if (dataHandlerReader != null) {
-                return dataHandlerReader.isDeferred();
-            } else {
-                throw new IllegalStateException();
-            }
-        } else {
-            if (getNode() instanceof OMText) {
-                // TODO: we should support deferred building of the DataHandler
-                return false;
-            } else {
-                throw new IllegalStateException();
-            }
-        }
-    }
-
-    public String getContentID() {
-        if (parser != null) {
-            if (dataHandlerReader != null) {
-                return dataHandlerReader.getContentID();
-            } else {
-                throw new IllegalStateException();
-            }
-        } else {
-            OMNode node = getNode();
-            if (node instanceof OMText) {
-                return ((OMText)node).getContentID();
-            } else {
-                throw new IllegalStateException();
-            }
-        }
-    }
-
-    public DataHandler getDataHandler() throws XMLStreamException {
-        if (parser != null) {
-            if (dataHandlerReader != null) {
-                return dataHandlerReader.getDataHandler();
-            } else {
-                throw new IllegalStateException();
-            }
-        } else {
-            OMNode node = getNode();
-            if (node instanceof OMText) {
-                return (DataHandler)((OMText)node).getDataHandler();
-            } else {
-                throw new IllegalStateException();
-            }
-        }
-    }
-
-    public DataHandlerProvider getDataHandlerProvider() {
-        if (parser != null) {
-            if (dataHandlerReader != null) {
-                return dataHandlerReader.getDataHandlerProvider();
-            } else {
-                throw new IllegalStateException();
-            }
-        } else {
-            throw new IllegalStateException();
-        }
-    }
-
-    /*
-     *
-     * ################################################################
-     * Generator methods for the OMNodes returned by the navigator
-     * ################################################################
-     *
-     */
-
-    /**
-     * Method generateEvents.
-     *
-     * @param node
-     * @return Returns int.
-     */
-    private int generateEvents(OMNode node) {
-        int returnEvent;
-        if (node == null) {
-            if (log.isDebugEnabled()) {
-                log.debug("Node is null...returning END_DOCUMENT");
-            }
-            returnEvent = END_DOCUMENT;
-            return returnEvent;
-        }
-        int nodeType = node.getType();
-        switch (nodeType) {
-            case OMNode.ELEMENT_NODE:
-                OMElement element = (OMElement) node;
-                returnEvent = generateElementEvents(element);
-                break;
-            case OMNode.TEXT_NODE:
-            case OMNode.SPACE_NODE:
-                returnEvent = generateTextEvents(node);
-                break;
-            case OMNode.COMMENT_NODE:
-                returnEvent = generateCommentEvents();
-                break;
-            case OMNode.CDATA_SECTION_NODE:
-                returnEvent = generateCdataEvents();
-                break;
-            case OMNode.PI_NODE:
-                returnEvent = PROCESSING_INSTRUCTION;
-                break;
-            default :
-                throw new OMStreamingException("Encountered node with unknown node type "
-                        + nodeType);
-        }
-        return returnEvent;
-    }
-
-    /**
-     * Method generateElementEvents.
-     *
-     * @param elt
-     * @return Returns int.
-     */
-    private int generateElementEvents(OMElement elt) {
-        if (nodeStack == null) {
-            nodeStack = new Stack();
-        }
-        int returnValue = START_ELEMENT;
-        if (!nodeStack.isEmpty() && nodeStack.peek().equals(elt)) {
-            returnValue = END_ELEMENT;
-            nodeStack.pop();
-        } else {
-            nodeStack.push(elt);
-        }
-        return returnValue;
-    }
-
-    /**
-     * Method generateTextEvents.
-     *
-     * @return Returns int.
-     */
-    private int generateTextEvents(OMNode node) {
-        OMText text = (OMText) node;
-        // If this is an optimized MTOM text node
-        // then simulate an XOP_INCLUDE element.
-        if (!isInlineMTOM() && 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;
-            }
-        } else {
-            return text.getType();
-        }
-    }
-    
-    /**
-     * @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.
-     *
-     * @return Returns int.
-     * @noinspection SameReturnValue
-     */
-    private int generateCommentEvents() {
-        return COMMENT;
-    }
-
-    /**
-     * Method generateCdataEvents.
-     *
-     * @return Returns int.
-     */
-    private int generateCdataEvents() {
-        return CDATA;
-    }
-
-    /*
-     * ####################################################################
-     * Other helper methods
-     * ####################################################################
-     */
-
-    /**
-     * helper method getCount.
-     *
-     * @param it
-     * @return Returns int.
-     */
-    private int getCount(Iterator it) {
-        int count = 0;
-        if (it != null) {
-            while (it.hasNext()) {
-                it.next();
-                count++;
-            }
-        }
-        return count;
-    }
-
-    /**
-     * Helper method getItemFromIterator.
-     *
-     * @param it
-     * @param index
-     * @return Returns Object.
-     */
-    private Object getItemFromIterator(Iterator it, int index) {
-        int count = 0;
-        Object returnObject = null;
-        boolean found = false;
-        if (it != null) {
-            while (it.hasNext()) {
-                returnObject = it.next();
-                if (index == count++) {
-                    found = true;
-                    break;
-                }
-            }
-        }
-        if (found) {
-            return returnObject;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Helper method getQName.
-     *
-     * @param element
-     * @return Returns QName.
-     */
-    private QName getQName(OMElement element) {
-        QName returnName;
-        OMNamespace ns = element.getNamespace();
-        String localPart = element.getLocalName();
-        if (ns != null) {
-            String prefix = ns.getPrefix();
-            String uri = ns.getNamespaceURI();
-            if ((prefix == null) || prefix.equals("")) {
-                returnName = new QName(uri, localPart);
-            } else {
-                returnName = new QName(uri, localPart, prefix);
-            }
-        } else {
-            returnName = new QName(localPart);
-        }
-        return returnName;
-    }
-
-    /**
-     * @param elt
-     * @param index
-     * @return Returns OMAttribute.
-     */
-    private OMAttribute getAttribute(OMElement elt, int index) {
-        OMAttribute returnAttrib = null;
-        if (elt != null) {
-            returnAttrib = (OMAttribute) getItemFromIterator(
-                    elt.getAllAttributes(), index);
-        }
-        return returnAttrib;
-    }
-
-    public void setParser(XMLStreamReader parser) {
-        this.parser = parser;
-        dataHandlerReader =
-                parser == null ? null : DataHandlerReaderUtil.getDataHandlerReader(parser);
-    }
-
-    private Map getAllNamespaces(OMNode contextNode) {
-        if (contextNode == null) {
-            return Collections.EMPTY_MAP;
-        }
-        OMContainer context;
-        if (contextNode instanceof OMContainer) {
-            context = (OMContainer)contextNode;
-        } else {
-            context = contextNode.getParent();
-        }
-        Map nsMap = new LinkedHashMap();
-        while (context != null && !(context instanceof OMDocument)) {
-            OMElement element = (OMElement) context;
-            Iterator i = element.getAllDeclaredNamespaces();
-            while (i != null && i.hasNext()) {
-                addNamespaceToMap((OMNamespace) i.next(), nsMap);
-            }
-            if (element.getNamespace() != null) {
-                addNamespaceToMap(element.getNamespace(), nsMap);
-            }
-            for (Iterator iter = element.getAllAttributes();
-                 iter != null && iter.hasNext();) {
-                OMAttribute attr = (OMAttribute) iter.next();
-                if (attr.getNamespace() != null) {
-                    addNamespaceToMap(attr.getNamespace(), nsMap);
-                }
-            }
-            context = element.getParent();
-        }
-        return nsMap;
-    }
-
-    private void addNamespaceToMap(OMNamespace ns, Map map) {
-        if (map.get(ns.getPrefix()) == null) {
-            map.put(ns.getPrefix(), ns.getNamespaceURI());
-        }
-    }
-
-    public OMXMLParserWrapper getBuilder() {
-        return builder;
-    }
-    
-    /**
-     * @return if parser is closed
-     */
-    public boolean isClosed() {
-        
-        // If there is a builder, the builder owns the parser
-        // and knows the isClosed status
-        if (builder != null && builder instanceof StAXBuilder) {
-           return ((StAXBuilder) builder).isClosed();
-        } else {
-            return _isClosed;
-        }
-    }
-    
-    /**
-     * Indicate if the parser resource should be release when closed.
-     * @param value boolean
-     */
-    public void releaseParserOnClose(boolean value) {
-        // if there is a StAXBuilder, it owns the parser 
-        // and controls the releaseOnClose status
-        if (builder != null && builder instanceof StAXBuilder) {
-            ((StAXBuilder) builder).releaseParserOnClose(value);
-            if (isClosed() && value) {
-                setParser(null);
-            }
-            return;
-        } else {
-            // Release parser if already closed
-            if (isClosed() && value) {
-                setParser(null);
-            }
-            _releaseParserOnClose = value;
-        }
-        
-    }
-
-    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;
-            // TODO: this is in contradiction with the Javadoc
-            //       which says that blobcid is the content ID without the surrounding
-            //       angle brackets and "cid:" prefix
-            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;  
+    public void setNamespaceURIInterning(boolean b) {
+        switchingWrapper.setNamespaceURIInterning(b);
     }
 }

Copied: webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/SwitchingWrapper.java (from r793246, webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/OMStAXWrapper.java)
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/SwitchingWrapper.java?p2=webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/SwitchingWrapper.java&p1=webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/OMStAXWrapper.java&r1=793246&r2=793345&rev=793345&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/OMStAXWrapper.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/SwitchingWrapper.java Sun Jul 12 13:26:19 2009
@@ -36,7 +36,6 @@
 
 import org.apache.axiom.ext.stax.datahandler.DataHandlerProvider;
 import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
-import org.apache.axiom.om.OMAttachmentAccessor;
 import org.apache.axiom.om.OMAttribute;
 import org.apache.axiom.om.OMComment;
 import org.apache.axiom.om.OMContainer;
@@ -48,7 +47,6 @@
 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.OMNavigator;
 import org.apache.axiom.om.impl.builder.DataHandlerReaderUtil;
@@ -60,13 +58,12 @@
 import org.apache.commons.logging.LogFactory;
 
 /**
- * Note - This class also implements the streaming constants interface to get access to the StAX
- * constants.
+ * Class used internally by {@link OMStAXWrapper}.
  */
-public class OMStAXWrapper extends AbstractXMLStreamReader
-    implements OMXMLStreamReader, DataHandlerReader, XMLStreamConstants {
+class SwitchingWrapper extends AbstractXMLStreamReader
+    implements DataHandlerReader, XMLStreamConstants {
     
-    private static final Log log = LogFactory.getLog(OMStAXWrapper.class);
+    private static final Log log = LogFactory.getLog(SwitchingWrapper.class);
     private static boolean DEBUG_ENABLED = log.isDebugEnabled();
     
     /** Field navigator */
@@ -105,13 +102,6 @@
     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 */
     private short state;
 
@@ -157,13 +147,6 @@
 
     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.
      *
@@ -197,29 +180,15 @@
         return this.namespaceURIInterning;
     }
     
-    
     /**
-     * When constructing the OMStaxWrapper, the creator must produce the builder (an instance of the
-     * OMXMLparserWrapper of the input) and the Element Node to start parsing. The wrapper will
-     * parse(proceed) until the end of the given element. Hence care should be taken to pass the
-     * root element if the entire document is needed.
-     *
-     * @param builder
-     * @param startNode
-     */
-    public OMStAXWrapper(OMXMLParserWrapper builder, OMElement startNode) {
-        this(builder, startNode, false);
-    }
-
-    /**
-     * Constructor OMStAXWrapper.
+     * Constructor.
      *
      * @param builder
      * @param startNode
      * @param cache
      */
-    public OMStAXWrapper(OMXMLParserWrapper builder, OMElement startNode,
-                         boolean cache) {
+    public SwitchingWrapper(OMXMLParserWrapper builder, OMElement startNode,
+                            boolean cache) {
 
         // create a navigator
         this.navigator = new OMNavigator(startNode);
@@ -265,7 +234,7 @@
         } else {
             if ((currentEvent == START_ELEMENT)
                     || (currentEvent == END_ELEMENT)) {
-                OMNamespace ns = ((OMElement) getNode()).getNamespace();
+                OMNamespace ns = ((OMElement) lastNode).getNamespace();
                 if (ns == null) {
                     return null;
                 } else {
@@ -290,7 +259,7 @@
             if ((currentEvent == START_ELEMENT)
                     || (currentEvent == END_ELEMENT)
                     || (currentEvent == NAMESPACE)) {
-                OMNamespace ns = ((OMElement) getNode()).getNamespace();
+                OMNamespace ns = ((OMElement) lastNode).getNamespace();
                 if (ns == null) {
                     returnStr = null;
                 } else {
@@ -337,7 +306,7 @@
             if ((currentEvent == START_ELEMENT)
                     || (currentEvent == END_ELEMENT)
                     || (currentEvent == ENTITY_REFERENCE)) {
-                return ((OMElement) getNode()).getLocalName();
+                return ((OMElement) lastNode).getLocalName();
             } else {
                 throw new IllegalStateException();
             }
@@ -354,7 +323,7 @@
         } else {
             if ((currentEvent == START_ELEMENT)
                     || (currentEvent == END_ELEMENT)) {
-                return getQName((OMElement) getNode());
+                return getQName((OMElement) lastNode);
             } else {
                 throw new IllegalStateException();
             }
@@ -445,9 +414,9 @@
             case CHARACTERS:
             case CDATA:
             case SPACE:
-                return ((OMText)getNode()).getText();
+                return ((OMText)lastNode).getText();
             case COMMENT:
-                return ((OMComment)getNode()).getValue();
+                return ((OMComment)lastNode).getValue();
             default:
                 throw new IllegalStateException();
         }
@@ -476,7 +445,7 @@
             if (isStartElement() || isEndElement()
                     || (currentEvent == NAMESPACE)) {
                 OMNamespace ns = (OMNamespace) getItemFromIterator(
-                        ((OMElement) getNode()).getAllDeclaredNamespaces(), i);
+                        ((OMElement) lastNode).getAllDeclaredNamespaces(), i);
                 returnString = (ns == null) ? null : ns.getNamespaceURI();
             }
         }
@@ -508,7 +477,7 @@
             if (isStartElement() || isEndElement()
                     || (currentEvent == NAMESPACE)) {
                 OMNamespace ns = (OMNamespace) getItemFromIterator(
-                        ((OMElement) getNode()).getAllDeclaredNamespaces(), i);
+                        ((OMElement) lastNode).getAllDeclaredNamespaces(), i);
                 if (ns != null) {
                     String prefix = ns.getPrefix();
                     returnString = prefix == null || prefix.length() == 0 ? null : prefix; 
@@ -528,7 +497,7 @@
         } else {
             if (isStartElement() || isEndElement()
                     || (currentEvent == NAMESPACE)) {
-                return getCount(((OMElement) getNode())
+                return getCount(((OMElement) lastNode)
                         .getAllDeclaredNamespaces());
             } else {
                 throw new IllegalStateException();
@@ -567,7 +536,7 @@
             returnString = parser.getAttributeValue(i);
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
+                OMAttribute attrib = getAttribute((OMElement) lastNode, i);
                 if (attrib != null) {
                     returnString = attrib.getAttributeValue();
                 }
@@ -590,7 +559,7 @@
             returnString = parser.getAttributeType(i);
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
+                OMAttribute attrib = getAttribute((OMElement) lastNode, i);
                 if (attrib != null) {
                     returnString = attrib.getAttributeType();
                 }
@@ -614,7 +583,7 @@
             returnString = parser.getAttributePrefix(i);
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
+                OMAttribute attrib = getAttribute((OMElement) lastNode, i);
                 if (attrib != null) {
                     OMNamespace nameSpace = attrib.getNamespace();
                     if (nameSpace != null) {
@@ -640,7 +609,7 @@
             returnString = parser.getAttributeLocalName(i);
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
+                OMAttribute attrib = getAttribute((OMElement) lastNode, i);
                 if (attrib != null) {
                     returnString = attrib.getLocalName();
                 }
@@ -663,7 +632,7 @@
             returnString = parser.getAttributeNamespace(i);
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMAttribute attrib = getAttribute((OMElement) getNode(), i);
+                OMAttribute attrib = getAttribute((OMElement) lastNode, i);
                 if (attrib != null) {
                     OMNamespace nameSpace = attrib.getNamespace();
                     if (nameSpace != null) {
@@ -689,7 +658,7 @@
             returnQName = parser.getAttributeName(i);
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                returnQName = getAttribute((OMElement) getNode(), i).getQName();
+                returnQName = getAttribute((OMElement) lastNode, i).getQName();
             } else {
                 throw new IllegalStateException(
                         "attribute count accessed in illegal event!");
@@ -708,7 +677,7 @@
             returnCount = parser.getAttributeCount();
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
-                OMElement elt = (OMElement) getNode();
+                OMElement elt = (OMElement) lastNode;
                 returnCount = getCount(elt.getAllAttributes());
             } else {
                 throw new IllegalStateException(
@@ -735,7 +704,7 @@
         } else {
             if (isStartElement() || (currentEvent == ATTRIBUTE)) {
                 QName qname = new QName(s, s1);
-                OMAttribute attrib = ((OMElement) getNode()).getAttribute(qname);
+                OMAttribute attrib = ((OMElement) lastNode).getAttribute(qname);
                 if (attrib != null) {
                     returnString = attrib.getAttributeValue();
                 }
@@ -837,10 +806,9 @@
             if (isStartElement() || isEndElement()
                     || (currentEvent == NAMESPACE)) {
 
-                OMNode node = getNode();
-                if (node instanceof OMElement) {
+                if (lastNode instanceof OMElement) {
                     OMNamespace namespaceURI =
-                            ((OMElement) node).findNamespaceURI(prefix);
+                            ((OMElement) lastNode).findNamespaceURI(prefix);
                     return namespaceURI != null ? namespaceURI.getNamespaceURI() : null;
                 }
             }
@@ -1031,15 +999,6 @@
      * @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 {
@@ -1126,17 +1085,8 @@
         if (state==SWITCHED){
             return parser.getNamespaceContext();
         }
-        Map m;
-        if (currentEvent == END_DOCUMENT) {
-            m = Collections.EMPTY_MAP;
-        } else {
-            m = getAllNamespaces(getNode());
-            if (getNode() != lastNode) {
-                // Handle situation involving substituted node.
-                m.putAll(getAllNamespaces(lastNode));
-            }
-        }
-        return new NamespaceContextImpl(m);
+        return new NamespaceContextImpl(
+                currentEvent == END_DOCUMENT ? Collections.EMPTY_MAP : getAllNamespaces(lastNode));
     }
 
     /**
@@ -1206,7 +1156,7 @@
             return parser.getPIData();
         } else {
             if (currentEvent == PROCESSING_INSTRUCTION) {
-                return ((OMProcessingInstruction)getNode()).getTarget();
+                return ((OMProcessingInstruction)lastNode).getTarget();
             } else {
                 throw new IllegalStateException();
             }
@@ -1223,7 +1173,7 @@
             return parser.getPIData();
         } else {
             if (currentEvent == PROCESSING_INSTRUCTION) {
-                return ((OMProcessingInstruction)getNode()).getValue();
+                return ((OMProcessingInstruction)lastNode).getValue();
             } else {
                 throw new IllegalStateException();
             }
@@ -1246,9 +1196,8 @@
                 return false;
             }
         } else {
-            OMNode node = getNode();
-            if (node instanceof OMText) {
-                return ((OMText)node).isBinary();
+            if (lastNode instanceof OMText) {
+                return ((OMText)lastNode).isBinary();
             } else {
                 return false;
             }
@@ -1263,7 +1212,7 @@
                 throw new IllegalStateException();
             }
         } else {
-            if (getNode() instanceof OMText) {
+            if (lastNode instanceof OMText) {
                 // TODO: we should support deferred building of the DataHandler
                 return false;
             } else {
@@ -1280,9 +1229,8 @@
                 throw new IllegalStateException();
             }
         } else {
-            OMNode node = getNode();
-            if (node instanceof OMText) {
-                return ((OMText)node).getContentID();
+            if (lastNode instanceof OMText) {
+                return ((OMText)lastNode).getContentID();
             } else {
                 throw new IllegalStateException();
             }
@@ -1297,9 +1245,8 @@
                 throw new IllegalStateException();
             }
         } else {
-            OMNode node = getNode();
-            if (node instanceof OMText) {
-                return (DataHandler)((OMText)node).getDataHandler();
+            if (lastNode instanceof OMText) {
+                return (DataHandler)((OMText)lastNode).getDataHandler();
             } else {
                 throw new IllegalStateException();
             }
@@ -1393,46 +1340,7 @@
      * @return Returns int.
      */
     private int generateTextEvents(OMNode node) {
-        OMText text = (OMText) node;
-        // If this is an optimized MTOM text node
-        // then simulate an XOP_INCLUDE element.
-        if (!isInlineMTOM() && 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;
-            }
-        } else {
-            return text.getType();
-        }
-    }
-    
-    /**
-     * @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;
+        return ((OMText)node).getType();
     }
 
     /**
@@ -1626,38 +1534,4 @@
         }
         
     }
-
-    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;
-            // TODO: this is in contradiction with the Javadoc
-            //       which says that blobcid is the content ID without the surrounding
-            //       angle brackets and "cid:" prefix
-            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-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java?rev=793345&r1=793344&r2=793345&view=diff
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java Sun Jul 12 13:26:19 2009
@@ -21,10 +21,12 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
+import java.util.Collections;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.activation.DataHandler;
 import javax.xml.namespace.NamespaceContext;
@@ -109,7 +111,7 @@
     private final DataHandlerReader dataHandlerReader;
     private int state = STATE_PASS_THROUGH;
     private String currentContentID;
-    private Map dataHandlerObjects = new HashMap();
+    private Map dataHandlerObjects = new LinkedHashMap();
 
     /**
      * Constructor.
@@ -141,16 +143,32 @@
     }
 
     /**
+     * Get the set of content IDs referenced in <tt>xop:Include</tt> element information items
+     * produced by this wrapper.
+     * 
+     * @return The set of content IDs in their order of appearance in the infoset. If no
+     *         <tt>xop:Include</tt> element information items have been produced yet, an empty
+     *         set will be returned.
+     */
+    public Set/*<String>*/ getContentIDs() {
+        return Collections.unmodifiableSet(dataHandlerObjects.keySet());
+    }
+
+    /**
      * Get the data handler for a given content ID.
      * 
      * @param contentID a content ID previously returned by an <tt>xop:Include</tt> element
      *                  produced by this reader
-     * @return the corresponding data handler
-     * @throws XMLStreamException if an error occurred while loading the data handler
+     * @return the corresponding data handler; may not be <code>null</code>
+     * @throws XMLStreamException if the content ID is unknown or an error occurred while loading
+     *         the data handler
      */
     public DataHandler getDataHandler(String contentID) throws XMLStreamException {
         Object dataHandlerObject = dataHandlerObjects.get(contentID);
-        if (dataHandlerObject instanceof DataHandler) {
+        if (dataHandlerObject == null) {
+            throw new XMLStreamException("No DataHandler object found for content ID '" +
+                    contentID + "'");
+        } else if (dataHandlerObject instanceof DataHandler) {
             return (DataHandler)dataHandlerObject;
         } else {
             return ((DataHandlerProvider)dataHandlerObject).getDataHandler();
@@ -370,7 +388,8 @@
     public String getAttributeValue(String namespaceURI, String localName) {
         switch (state) {
             case STATE_XOP_INCLUDE_START_ELEMENT:
-                if (namespaceURI == null && localName.equals("href")) {
+                if ((namespaceURI == null || namespaceURI.length() == 0)
+                        && localName.equals("href")) {
                     return "cid:" + currentContentID;
                 } else {
                     return null;



Mime
View raw message