You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by ve...@apache.org on 2013/05/18 10:45:53 UTC

svn commit: r1484070 - in /webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common: ./ serializer/pull/

Author: veithen
Date: Sat May 18 08:45:53 2013
New Revision: 1484070

URL: http://svn.apache.org/r1484070
Log:
Improved and clarified the design of the StAX pull serializer (which uses the state pattern).

Added:
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/ClosedState.java
      - copied, changed from r1483917, webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/ClosedReader.java
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDTDReader.java   (with props)
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDataHandlerReader.java   (with props)
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/OMXMLStreamReaderExAdapter.java
      - copied, changed from r1483917, webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/OMStAXWrapper.java
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullSerializer.java
      - copied, changed from r1483917, webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/StreamSwitch.java
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullSerializerState.java   (with props)
Removed:
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/ClosedReader.java
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/OMStAXWrapper.java
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/StreamSwitch.java
Modified:
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/AbstractWrapper.java
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/IncludeWrapper.java
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullThroughWrapper.java
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/SwitchingWrapper.java

Modified: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java?rev=1484070&r1=1484069&r2=1484070&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java (original)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java Sat May 18 08:45:53 2013
@@ -31,7 +31,8 @@ import org.apache.axiom.om.impl.OMNodeEx
 import org.apache.axiom.om.impl.builder.OMFactoryEx;
 import org.apache.axiom.om.impl.builder.StAXBuilder;
 import org.apache.axiom.om.impl.builder.StAXOMBuilder;
-import org.apache.axiom.om.impl.common.serializer.pull.OMStAXWrapper;
+import org.apache.axiom.om.impl.common.serializer.pull.OMXMLStreamReaderExAdapter;
+import org.apache.axiom.om.impl.common.serializer.pull.PullSerializer;
 import org.apache.axiom.om.util.OMXMLStreamReaderValidator;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -62,13 +63,13 @@ public final class OMContainerHelper {
         boolean done = container.isComplete();
         // TODO: review & clean up
         if ((builder == null) && done) {
-            reader = new OMStAXWrapper(null, container, cache, configuration.isPreserveNamespaceContext());
+            reader = new OMXMLStreamReaderExAdapter(new PullSerializer(null, container, cache, configuration.isPreserveNamespaceContext()));
         } else {
             if (builder != null && builder.isCompleted() && !cache && !done) {
                 throw new UnsupportedOperationException(
                 "The parser is already consumed!");
             }
-            reader = new OMStAXWrapper(builder, container, cache, configuration.isPreserveNamespaceContext());
+            reader = new OMXMLStreamReaderExAdapter(new PullSerializer(builder, container, cache, configuration.isPreserveNamespaceContext()));
         }
         
         if (configuration.isNamespaceURIInterning()) {

Modified: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/AbstractWrapper.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/AbstractWrapper.java?rev=1484070&r1=1484069&r2=1484070&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/AbstractWrapper.java (original)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/AbstractWrapper.java Sat May 18 08:45:53 2013
@@ -18,39 +18,93 @@
  */
 package org.apache.axiom.om.impl.common.serializer.pull;
 
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 
-import org.apache.axiom.util.stax.wrapper.XMLStreamReaderWrapper;
+import org.apache.axiom.ext.stax.DTDReader;
+import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
+import org.apache.axiom.om.OMDataSource;
+import org.apache.axiom.util.stax.XMLStreamReaderUtils;
 
+/**
+ * Base class for {@link PullSerializerState} implementations that wrap an {@link XMLStreamReader}.
+ */
 //TODO: what about the close() method?
-abstract class AbstractWrapper extends XMLStreamReaderWrapper {
-    private final StreamSwitch streamSwitch;
-    private final XMLStreamReader nextTarget;
+// TODO: make methods final
+abstract class AbstractWrapper extends PullSerializerState {
+    protected final XMLStreamReader reader;
+    private final PullSerializer serializer;
+    private final PullSerializerState nextState;
     private int depth;
-
-    AbstractWrapper(StreamSwitch streamSwitch, XMLStreamReader nextTarget,
-            XMLStreamReader parent, int startDepth) {
-        super(parent);
-        this.streamSwitch = streamSwitch;
-        this.nextTarget = nextTarget;
+    
+    /**
+     * The {@link DTDReader} extension of the reader, or <code>null</code> if the extension has not
+     * yet been retrieved.
+     */
+    private DTDReader dtdReader;
+    
+    /**
+     * The {@link DataHandlerReader} extension of the reader, or <code>null</code> if the extension
+     * has not yet been retrieved.
+     */
+    private DataHandlerReader dataHandlerReader;
+
+    AbstractWrapper(PullSerializer streamSwitch, PullSerializerState nextState,
+            XMLStreamReader reader, int startDepth) {
+        this.reader = reader;
+        this.serializer = streamSwitch;
+        this.nextState = nextState;
         depth = startDepth;
     }
 
-    public int next() throws XMLStreamException {
+    final DTDReader getDTDReader() {
+        if (dtdReader == null) {
+            try {
+                dtdReader = (DTDReader)reader.getProperty(DTDReader.PROPERTY);
+            } catch (IllegalArgumentException ex) {
+                // Continue
+            }
+            if (dtdReader == null) {
+                dtdReader = NullDTDReader.INSTANCE;
+            }
+        }
+        return dtdReader;
+    }
+
+    final DataHandlerReader getDataHandlerReader() {
+        if (dataHandlerReader == null) {
+            dataHandlerReader = XMLStreamReaderUtils.getDataHandlerReader(reader);
+            if (dataHandlerReader == null) {
+                dataHandlerReader = NullDataHandlerReader.INSTANCE;
+            }
+        }
+        return dataHandlerReader;
+    }
+
+    int getEventType() {
+        return reader.getEventType();
+    }
+
+    boolean hasNext() throws XMLStreamException {
+        return reader.hasNext();
+    }
+
+    int next() throws XMLStreamException {
         if (depth == 0) {
             // We get here if the underlying XMLStreamReader is on the last END_ELEMENT event
             // TODO: also do this if the reader is prematurely closed
             release();
-            streamSwitch.setParent(nextTarget);
-            return nextTarget.next();
+            serializer.switchState(nextState);
+            return nextState.next();
         } else {
-            int event = super.next();
+            int event = reader.next();
             switch (event) {
-                case START_ELEMENT:
+                case XMLStreamReader.START_ELEMENT:
                     depth++;
                     break;
-                case END_ELEMENT:
+                case XMLStreamReader.END_ELEMENT:
                     depth--;
                     break;
             }
@@ -58,18 +112,159 @@ abstract class AbstractWrapper extends X
         }
     }
     
-    public int nextTag() throws XMLStreamException {
+    int nextTag() throws XMLStreamException {
         // TODO: need to handle depth == 0 case here!
-        int result = super.nextTag();
+        int result = reader.nextTag();
         switch (result) {
-            case START_ELEMENT:
+            case XMLStreamReader.START_ELEMENT:
                 depth++;
                 break;
-            case END_ELEMENT:
+            case XMLStreamReader.END_ELEMENT:
                 depth--;
         }
         return result;
     }
 
+    void close() throws XMLStreamException {
+        reader.close();
+    }
+
+    Object getProperty(String name) throws IllegalArgumentException {
+        return reader.getProperty(name);
+    }
+
+    String getVersion() {
+        return reader.getVersion();
+    }
+
+    String getCharacterEncodingScheme() {
+        return reader.getCharacterEncodingScheme();
+    }
+
+    String getEncoding() {
+        return reader.getEncoding();
+    }
+
+    boolean isStandalone() {
+        return reader.isStandalone();
+    }
+
+    boolean standaloneSet() {
+        return reader.standaloneSet();
+    }
+
+    String getPrefix() {
+        return reader.getPrefix();
+    }
+
+    String getNamespaceURI() {
+        return reader.getNamespaceURI();
+    }
+
+    String getLocalName() {
+        return reader.getLocalName();
+    }
+
+    QName getName() {
+        return reader.getName();
+    }
+
+    int getNamespaceCount() {
+        return reader.getNamespaceCount();
+    }
+
+    String getNamespacePrefix(int index) {
+        return reader.getNamespacePrefix(index);
+    }
+
+    String getNamespaceURI(int index) {
+        return reader.getNamespaceURI(index);
+    }
+
+    int getAttributeCount() {
+        return reader.getAttributeCount();
+    }
+
+    String getAttributePrefix(int index) {
+        return reader.getAttributePrefix(index);
+    }
+
+    String getAttributeNamespace(int index) {
+        return reader.getAttributeNamespace(index);
+    }
+
+    String getAttributeLocalName(int index) {
+        return reader.getAttributeLocalName(index);
+    }
+
+    QName getAttributeName(int index) {
+        return reader.getAttributeName(index);
+    }
+
+    boolean isAttributeSpecified(int index) {
+        return reader.isAttributeSpecified(index);
+    }
+
+    String getAttributeType(int index) {
+        return reader.getAttributeType(index);
+    }
+
+    String getAttributeValue(int index) {
+        return reader.getAttributeValue(index);
+    }
+
+    String getAttributeValue(String namespaceURI, String localName) {
+        return reader.getAttributeValue(namespaceURI, localName);
+    }
+
+    NamespaceContext getNamespaceContext() {
+        return reader.getNamespaceContext();
+    }
+
+    String getNamespaceURI(String prefix) {
+        return reader.getNamespaceURI(prefix);
+    }
+
+    String getElementText() throws XMLStreamException {
+        return reader.getElementText();
+    }
+
+    String getText() {
+        return reader.getText();
+    }
+
+    char[] getTextCharacters() {
+        return reader.getTextCharacters();
+    }
+
+    int getTextStart() {
+        return reader.getTextStart();
+    }
+
+    int getTextLength() {
+        return reader.getTextLength();
+    }
+
+    int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
+            throws XMLStreamException {
+        return reader.getTextCharacters(sourceStart, target, targetStart, length);
+    }
+
+    Boolean isWhiteSpace() {
+        return Boolean.valueOf(reader.isWhiteSpace());
+    }
+
+    String getPIData() {
+        return reader.getPIData();
+    }
+
+    String getPITarget() {
+        return reader.getPITarget();
+    }
+
+    OMDataSource getDataSource() {
+        return null;
+    }
+
     abstract void release() throws XMLStreamException;
 }

Copied: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/ClosedState.java (from r1483917, webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/ClosedReader.java)
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/ClosedState.java?p2=webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/ClosedState.java&p1=webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/ClosedReader.java&r1=1483917&r2=1484070&rev=1484070&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/ClosedReader.java (original)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/ClosedState.java Sat May 18 08:45:53 2013
@@ -20,193 +20,179 @@ package org.apache.axiom.om.impl.common.
 
 import javax.xml.namespace.NamespaceContext;
 import javax.xml.namespace.QName;
-import javax.xml.stream.Location;
 import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
 
-final class ClosedReader implements XMLStreamReader {
-    static final ClosedReader INSTANCE = new ClosedReader();
-    
-    private ClosedReader() {}
-
-    public void close() throws XMLStreamException {
-        // no-op
-    }
-
-    public Object getProperty(String name) throws IllegalArgumentException {
-        return null;
-    }
-
-    public int getAttributeCount() {
-        throw new IllegalStateException("Reader already closed");
-    }
+import org.apache.axiom.ext.stax.DTDReader;
+import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
+import org.apache.axiom.om.OMDataSource;
 
-    public String getAttributeLocalName(int index) {
-        throw new IllegalStateException("Reader already closed");
-    }
+final class ClosedState extends PullSerializerState {
+    static final ClosedState INSTANCE = new ClosedState();
+    
+    private ClosedState() {}
 
-    public QName getAttributeName(int index) {
-        throw new IllegalStateException("Reader already closed");
+    DTDReader getDTDReader() {
+        return NullDTDReader.INSTANCE;
     }
 
-    public String getAttributeNamespace(int index) {
-        throw new IllegalStateException("Reader already closed");
+    DataHandlerReader getDataHandlerReader() {
+        return NullDataHandlerReader.INSTANCE;
     }
 
-    public String getAttributePrefix(int index) {
-        throw new IllegalStateException("Reader already closed");
+    void close() throws XMLStreamException {
+        // no-op
     }
 
-    public String getAttributeType(int index) {
-        throw new IllegalStateException("Reader already closed");
+    Object getProperty(String name) throws IllegalArgumentException {
+        return null;
     }
 
-    public String getAttributeValue(int index) {
+    int getAttributeCount() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getAttributeValue(String namespaceURI, String localName) {
+    String getAttributeLocalName(int index) {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getCharacterEncodingScheme() {
+    QName getAttributeName(int index) {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getElementText() throws XMLStreamException {
+    String getAttributeNamespace(int index) {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getEncoding() {
+    String getAttributePrefix(int index) {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public int getEventType() {
+    String getAttributeType(int index) {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getLocalName() {
+    String getAttributeValue(int index) {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public Location getLocation() {
+    String getAttributeValue(String namespaceURI, String localName) {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public QName getName() {
+    String getCharacterEncodingScheme() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public NamespaceContext getNamespaceContext() {
+    String getElementText() throws XMLStreamException {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public int getNamespaceCount() {
+    String getEncoding() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getNamespacePrefix(int index) {
+    int getEventType() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getNamespaceURI() {
+    String getLocalName() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getNamespaceURI(String prefix) {
+    QName getName() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getNamespaceURI(int index) {
+    NamespaceContext getNamespaceContext() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getPIData() {
+    int getNamespaceCount() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getPITarget() {
+    String getNamespacePrefix(int index) {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getPrefix() {
+    String getNamespaceURI() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getText() {
+    String getNamespaceURI(String prefix) {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public char[] getTextCharacters() {
+    String getNamespaceURI(int index) {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
-            throws XMLStreamException {
+    String getPIData() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public int getTextLength() {
+    String getPITarget() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public int getTextStart() {
+    String getPrefix() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public String getVersion() {
+    String getText() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public boolean hasName() {
+    char[] getTextCharacters() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public boolean hasNext() throws XMLStreamException {
+    int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
+            throws XMLStreamException {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public boolean hasText() {
+    int getTextLength() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public boolean isAttributeSpecified(int index) {
+    int getTextStart() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public boolean isCharacters() {
+    String getVersion() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public boolean isEndElement() {
+    boolean hasNext() throws XMLStreamException {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public boolean isStandalone() {
+    boolean isAttributeSpecified(int index) {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public boolean isStartElement() {
+    boolean isStandalone() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public boolean isWhiteSpace() {
+    Boolean isWhiteSpace() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public int next() throws XMLStreamException {
+    int next() throws XMLStreamException {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public int nextTag() throws XMLStreamException {
+    int nextTag() throws XMLStreamException {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
+    public boolean standaloneSet() {
         throw new IllegalStateException("Reader already closed");
     }
 
-    public boolean standaloneSet() {
+    OMDataSource getDataSource() {
         throw new IllegalStateException("Reader already closed");
     }
 }

Modified: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/IncludeWrapper.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/IncludeWrapper.java?rev=1484070&r1=1484069&r2=1484070&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/IncludeWrapper.java (original)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/IncludeWrapper.java Sat May 18 08:45:53 2013
@@ -22,11 +22,11 @@ import javax.xml.stream.XMLStreamExcepti
 import javax.xml.stream.XMLStreamReader;
 
 final class IncludeWrapper extends AbstractWrapper {
-    IncludeWrapper(StreamSwitch streamSwitch, XMLStreamReader nextTarget, XMLStreamReader parent) {
-        super(streamSwitch, nextTarget, parent, 1);
+    IncludeWrapper(PullSerializer serializer, PullSerializerState nextState, XMLStreamReader parent) {
+        super(serializer, nextState, parent, 1);
     }
 
     void release() throws XMLStreamException {
-        getParent().close();
+        reader.close();
     }
 }

Added: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDTDReader.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDTDReader.java?rev=1484070&view=auto
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDTDReader.java (added)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDTDReader.java Sat May 18 08:45:53 2013
@@ -0,0 +1,39 @@
+/*
+ * 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.impl.common.serializer.pull;
+
+import org.apache.axiom.ext.stax.DTDReader;
+
+final class NullDTDReader implements DTDReader {
+    static final NullDTDReader INSTANCE = new NullDTDReader();
+    
+    private NullDTDReader() {}
+
+    public String getRootName() {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getPublicId() {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getSystemId() {
+        throw new UnsupportedOperationException();
+    }
+}

Propchange: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDTDReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDataHandlerReader.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDataHandlerReader.java?rev=1484070&view=auto
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDataHandlerReader.java (added)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDataHandlerReader.java Sat May 18 08:45:53 2013
@@ -0,0 +1,55 @@
+/*
+ * 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.impl.common.serializer.pull;
+
+import javax.activation.DataHandler;
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.axiom.ext.stax.datahandler.DataHandlerProvider;
+import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
+
+final class NullDataHandlerReader implements DataHandlerReader {
+    static final NullDataHandlerReader INSTANCE = new NullDataHandlerReader();
+    
+    private NullDataHandlerReader() {}
+
+    public boolean isBinary() {
+        return false;
+    }
+
+    public boolean isOptimized() {
+        throw new IllegalStateException();
+    }
+
+    public boolean isDeferred() {
+        throw new IllegalStateException();
+    }
+
+    public String getContentID() {
+        throw new IllegalStateException();
+    }
+
+    public DataHandler getDataHandler() throws XMLStreamException {
+        throw new IllegalStateException();
+    }
+
+    public DataHandlerProvider getDataHandlerProvider() {
+        throw new IllegalStateException();
+    }
+}

Propchange: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/NullDataHandlerReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/OMXMLStreamReaderExAdapter.java (from r1483917, webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/OMStAXWrapper.java)
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/OMXMLStreamReaderExAdapter.java?p2=webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/OMXMLStreamReaderExAdapter.java&p1=webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/OMStAXWrapper.java&r1=1483917&r2=1484070&rev=1484070&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/OMStAXWrapper.java (original)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/OMXMLStreamReaderExAdapter.java Sat May 18 08:45:53 2013
@@ -16,19 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.axiom.om.impl.common.serializer.pull;
 
 import java.io.IOException;
 
 import javax.activation.DataHandler;
-import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.util.StreamReaderDelegate;
 
-import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMDataSource;
 import org.apache.axiom.om.OMException;
-import org.apache.axiom.om.OMXMLParserWrapper;
+import org.apache.axiom.om.OMXMLStreamReader;
 import org.apache.axiom.om.impl.OMXMLStreamReaderEx;
 import org.apache.axiom.util.stax.xop.ContentIDGenerator;
 import org.apache.axiom.util.stax.xop.OptimizationPolicy;
@@ -37,28 +34,20 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 /**
- * {@link XMLStreamReader} implementation that generates events from a given Axiom tree.
- * This class does intentionally does not implement XMLStreamReaderContainer because
- * it does not wrap a parser (it wraps an OM graph).
+ * Adapter that adds the {@link OMXMLStreamReaderEx} interface to a {@link PullSerializer}.
+ * <p>
+ * Note that this class will disappear in Axiom 1.3 because the methods defined by
+ * {@link OMXMLStreamReader} are deprecated.
  */
-public class OMStAXWrapper extends StreamReaderDelegate implements OMXMLStreamReaderEx {
-    private static final Log log = LogFactory.getLog(OMStAXWrapper.class);
+public class OMXMLStreamReaderExAdapter extends StreamReaderDelegate implements OMXMLStreamReaderEx {
+    private static final Log log = LogFactory.getLog(OMXMLStreamReaderExAdapter.class);
     
-    private final StreamSwitch streamSwitch = new StreamSwitch();
+    private final PullSerializer serializer;
     private XOPEncodingStreamReader xopEncoder;
     
-    /**
-     * Constructor OMStAXWrapper.
-     *
-     * @param builder
-     * @param startNode
-     * @param cache
-     * @param preserveNamespaceContext
-     */
-    public OMStAXWrapper(OMXMLParserWrapper builder, OMContainer startNode,
-                         boolean cache, boolean preserveNamespaceContext) {
-        streamSwitch.setParent(new SwitchingWrapper(streamSwitch, builder, startNode, cache, preserveNamespaceContext));
-        setParent(streamSwitch);
+    public OMXMLStreamReaderExAdapter(PullSerializer serializer) {
+        super(serializer);
+        this.serializer = serializer;
     }
 
     public boolean isInlineMTOM() {
@@ -72,14 +61,14 @@ public class OMStAXWrapper extends Strea
         if (value) {
             if (xopEncoder != null) {
                 xopEncoder = null;
-                setParent(streamSwitch);
+                setParent(serializer);
             }
         } else {
             if (xopEncoder == null) {
                 // Since the intention is to support an efficient way to pass binary content to a
                 // consumer that is not aware of our data handler extension (see AXIOM-202), we
                 // use OptimizationPolicy.ALL, i.e. we ignore OMText#isOptimized().
-                xopEncoder = new XOPEncodingStreamReader(streamSwitch, ContentIDGenerator.DEFAULT,
+                xopEncoder = new XOPEncodingStreamReader(serializer, ContentIDGenerator.DEFAULT,
                         OptimizationPolicy.ALL);
                 setParent(xopEncoder);
             }
@@ -108,10 +97,10 @@ public class OMStAXWrapper extends Strea
     }
     
     public OMDataSource getDataSource() {
-        return streamSwitch.getDataSource();
+        return serializer.getDataSource();
     }
     
     public void enableDataSourceEvents(boolean value) {
-        streamSwitch.enableDataSourceEvents(value);
+        serializer.enableDataSourceEvents(value);
     }
 }

Copied: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullSerializer.java (from r1483917, webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/StreamSwitch.java)
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullSerializer.java?p2=webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullSerializer.java&p1=webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/StreamSwitch.java&r1=1483917&r2=1484070&rev=1484070&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/StreamSwitch.java (original)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullSerializer.java Sat May 18 08:45:53 2013
@@ -19,51 +19,43 @@
 package org.apache.axiom.om.impl.common.serializer.pull;
 
 import javax.activation.DataHandler;
-import javax.xml.stream.XMLStreamConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.util.StreamReaderDelegate;
 
 import org.apache.axiom.ext.stax.DTDReader;
 import org.apache.axiom.ext.stax.datahandler.DataHandlerProvider;
 import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
+import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMDataSource;
+import org.apache.axiom.om.OMXMLParserWrapper;
+import org.apache.axiom.util.stax.AbstractXMLStreamReader;
 import org.apache.axiom.util.stax.XMLStreamReaderUtils;
 
-final class StreamSwitch extends StreamReaderDelegate implements DataHandlerReader, DTDReader {
+/**
+ * {@link XMLStreamReader} implementation that generates events from a given Axiom tree.
+ */
+public final class PullSerializer extends AbstractXMLStreamReader implements DataHandlerReader, DTDReader {
+    private PullSerializerState state;
+    
     /**
      * Indicates if an OMSourcedElement with an OMDataSource should
      * be considered as an interior node or a leaf node.
      */
     private boolean isDataSourceALeaf;
 
-    /**
-     * The {@link DataHandlerReader} extension of the parent, or <code>null</code> if the parser
-     * doesn't support this extension.
-     */
-    private DataHandlerReader dataHandlerReader;
+    public PullSerializer(OMXMLParserWrapper builder, OMContainer startNode,
+            boolean cache, boolean preserveNamespaceContext) {
+        state = new SwitchingWrapper(this, builder, startNode, cache, preserveNamespaceContext);
+    }
     
-    /**
-     * The {@link DTDReader} extension of the parent, or <code>null</code> if the parser doesn't
-     * support this extension.
-     */
-    private DTDReader dtdReader;
-
-    public void setParent(XMLStreamReader reader) {
-        super.setParent(reader);
-        dataHandlerReader =
-                reader == null ? null : XMLStreamReaderUtils.getDataHandlerReader(reader);
-        try {
-            dtdReader = (DTDReader)reader.getProperty(DTDReader.PROPERTY);
-        } catch (IllegalArgumentException ex) {
-            dtdReader = null;
-        }
+    void switchState(PullSerializerState state) {
+        this.state = state;
     }
 
     OMDataSource getDataSource() {
-        XMLStreamReader parent = getParent();
-        // Only SwitchingWrapper can produce OMDataSource "events"
-        return parent instanceof SwitchingWrapper ? ((SwitchingWrapper)getParent()).getDataSource() : null;
+        return state.getDataSource();
     }
     
     void enableDataSourceEvents(boolean value) {
@@ -74,66 +66,25 @@ final class StreamSwitch extends StreamR
         return isDataSourceALeaf;
     }
 
+    public int getEventType() {
+        return state.getEventType();
+    }
+
+    public boolean hasNext() throws XMLStreamException {
+        return state.hasNext();
+    }
+
+    public int next() throws XMLStreamException {
+        return state.next();
+    }
+
     public int nextTag() throws XMLStreamException {
-        // The nextTag method is tricky because the delegate may need to switch
-        // to another delegate to locate the next tag. We allow the delegate to
-        // return -1 in this case.
-        int eventType = super.nextTag();
-        if (eventType == -1) {
-            eventType = next();
-            while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip whitespace
-                    || (eventType == XMLStreamConstants.CDATA && isWhiteSpace()) // skip whitespace
-                    || eventType == XMLStreamConstants.SPACE
-                    || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
-                    || eventType == XMLStreamConstants.COMMENT) {
-                eventType = next();
-            }
-            if (eventType != XMLStreamConstants.START_ELEMENT &&
-                    eventType != XMLStreamConstants.END_ELEMENT) {
-                throw new XMLStreamException("expected start or end tag", getLocation());
-            }
-        }
-        return eventType;
+        int eventType = state.nextTag();
+        return eventType == -1 ? super.nextTag() : eventType;
     }
 
-    public String getElementText() throws XMLStreamException {
-        // getElementText is tricky for the same reasons as nextTag.
-        String text = super.getElementText();
-        if (text != null) {
-            return text;
-        } 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();
-            ///////////////////////////////////////////////////////////////
-        }
+    public void close() throws XMLStreamException {
+        state.close();
     }
 
     public Object getProperty(String name) {
@@ -143,79 +94,173 @@ final class StreamSwitch extends StreamR
         } else if (DTDReader.PROPERTY.equals(name)) {
             return this;
         } else {
-            return super.getProperty(name);
+            return state.getProperty(name);
         }
     }
 
+    public String getVersion() {
+        return state.getVersion();
+    }
+
+    public String getCharacterEncodingScheme() {
+        return state.getCharacterEncodingScheme();
+    }
+
+    public String getEncoding() {
+        return state.getEncoding();
+    }
+
+    public boolean isStandalone() {
+        return state.isStandalone();
+    }
+
+    public boolean standaloneSet() {
+        return state.standaloneSet();
+    }
+
+    public String getPrefix() {
+        return state.getPrefix();
+    }
+
+    public String getNamespaceURI() {
+        return state.getNamespaceURI();
+    }
+
+    public String getLocalName() {
+        return state.getLocalName();
+    }
+
+    public QName getName() {
+        return state.getName();
+    }
+
+    public int getNamespaceCount() {
+        return state.getNamespaceCount();
+    }
+
+    public String getNamespacePrefix(int index) {
+        return state.getNamespacePrefix(index);
+    }
+
+    public String getNamespaceURI(int index) {
+        return state.getNamespaceURI(index);
+    }
+
+    public int getAttributeCount() {
+        return state.getAttributeCount();
+    }
+
+    public String getAttributePrefix(int index) {
+        return state.getAttributePrefix(index);
+    }
+
+    public String getAttributeNamespace(int index) {
+        return state.getAttributeNamespace(index);
+    }
+
+    public String getAttributeLocalName(int index) {
+        return state.getAttributeLocalName(index);
+    }
+
+    public QName getAttributeName(int index) {
+        return state.getAttributeName(index);
+    }
+
+    public boolean isAttributeSpecified(int index) {
+        return state.isAttributeSpecified(index);
+    }
+
+    public String getAttributeType(int index) {
+        return state.getAttributeType(index);
+    }
+
+    public String getAttributeValue(int index) {
+        return state.getAttributeValue(index);
+    }
+
+    public String getAttributeValue(String namespaceURI, String localName) {
+        return state.getAttributeValue(namespaceURI, localName);
+    }
+
+    public NamespaceContext getNamespaceContext() {
+        return state.getNamespaceContext();
+    }
+
+    public String getNamespaceURI(String prefix) {
+        return state.getNamespaceURI(prefix);
+    }
+
+    public String getElementText() throws XMLStreamException {
+        String text = state.getElementText();
+        return text == null ? super.getElementText() : text;
+    }
+
+    public String getText() {
+        return state.getText();
+    }
+
+    public char[] getTextCharacters() {
+        return state.getTextCharacters();
+    }
+
+    public int getTextStart() {
+        return state.getTextStart();
+    }
+
+    public int getTextLength() {
+        return state.getTextLength();
+    }
+
+    public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {
+        return state.getTextCharacters(sourceStart, target, targetStart, length);
+    }
+
+    public boolean isWhiteSpace() {
+        Boolean isWhiteSpace = state.isWhiteSpace();
+        return isWhiteSpace == null ? super.isWhiteSpace() : isWhiteSpace.booleanValue();
+    }
+
+    public String getPIData() {
+        return state.getPIData();
+    }
+
+    public String getPITarget() {
+        return state.getPITarget();
+    }
+    
     public boolean isBinary() {
-        if (dataHandlerReader != null) {
-            return dataHandlerReader.isBinary();
-        } else {
-            return false;
-        }
+        return state.getDataHandlerReader().isBinary();
     }
 
     public boolean isOptimized() {
-        if (dataHandlerReader != null) {
-            return dataHandlerReader.isOptimized();
-        } else {
-            throw new IllegalStateException();
-        }
+        return state.getDataHandlerReader().isOptimized();
     }
 
     public boolean isDeferred() {
-        if (dataHandlerReader != null) {
-            return dataHandlerReader.isDeferred();
-        } else {
-            throw new IllegalStateException();
-        }
+        return state.getDataHandlerReader().isDeferred();
     }
 
     public String getContentID() {
-        if (dataHandlerReader != null) {
-            return dataHandlerReader.getContentID();
-        } else {
-            throw new IllegalStateException();
-        }
+        return state.getDataHandlerReader().getContentID();
     }
 
     public DataHandler getDataHandler() throws XMLStreamException {
-        if (dataHandlerReader != null) {
-            return dataHandlerReader.getDataHandler();
-        } else {
-            throw new IllegalStateException();
-        }
+        return state.getDataHandlerReader().getDataHandler();
     }
 
     public DataHandlerProvider getDataHandlerProvider() {
-        if (dataHandlerReader != null) {
-            return dataHandlerReader.getDataHandlerProvider();
-        } else {
-            throw new IllegalStateException();
-        }
+        return state.getDataHandlerReader().getDataHandlerProvider();
     }
 
     public String getRootName() {
-        if (dtdReader != null) {
-            return dtdReader.getRootName();
-        } else {
-            throw new UnsupportedOperationException();
-        }
+        return state.getDTDReader().getRootName();
     }
 
     public String getPublicId() {
-        if (dtdReader != null) {
-            return dtdReader.getPublicId();
-        } else {
-            throw new UnsupportedOperationException();
-        }
+        return state.getDTDReader().getPublicId();
     }
 
     public String getSystemId() {
-        if (dtdReader != null) {
-            return dtdReader.getSystemId();
-        } else {
-            throw new UnsupportedOperationException();
-        }
+        return state.getDTDReader().getSystemId();
     }
 }

Added: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullSerializerState.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullSerializerState.java?rev=1484070&view=auto
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullSerializerState.java (added)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullSerializerState.java Sat May 18 08:45:53 2013
@@ -0,0 +1,159 @@
+/*
+ * 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.impl.common.serializer.pull;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.ext.stax.DTDReader;
+import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
+import org.apache.axiom.om.OMDataSource;
+import org.apache.axiom.om.impl.OMXMLStreamReaderEx;
+
+abstract class PullSerializerState {
+    /**
+     * Get the {@link DTDReader} extension.
+     * 
+     * @return the {@link DTDReader} extension; must not be <code>null</code>
+     */
+    abstract DTDReader getDTDReader();
+    
+    /**
+     * Get the {@link DataHandlerReader} extension.
+     * 
+     * @return the {@link DataHandlerReader} extension; must not be <code>null</code>
+     */
+    abstract DataHandlerReader getDataHandlerReader();
+    
+    abstract int getEventType();
+
+    abstract boolean hasNext() throws XMLStreamException;
+
+    abstract int next() throws XMLStreamException;
+
+    /**
+     * Skip to the next {@link XMLStreamConstants#START_ELEMENT} or
+     * {@link XMLStreamConstants#END_ELEMENT} event. This method has the same contract as
+     * {@link XMLStreamReader#nextTag()}, except that it is an optional operation: if the
+     * implementation can't satisfy the request, it can return -1 to let {@link PullSerializer}
+     * handle it. The reason is that skipping to the next start or end element event may require
+     * switching to another state.
+     * 
+     * @return the event type, or -1 if the request could be satisfied
+     * @throws XMLStreamException
+     */
+    abstract int nextTag() throws XMLStreamException ;
+
+    abstract void close() throws XMLStreamException;
+
+    abstract Object getProperty(String name) throws IllegalArgumentException;
+
+    abstract String getVersion();
+
+    abstract String getCharacterEncodingScheme();
+
+    abstract String getEncoding();
+
+    abstract boolean isStandalone();
+
+    abstract boolean standaloneSet();
+
+    abstract String getPrefix();
+
+    abstract String getNamespaceURI();
+
+    abstract String getLocalName();
+
+    abstract QName getName();
+
+    abstract int getNamespaceCount();
+
+    abstract String getNamespacePrefix(int index);
+
+    abstract String getNamespaceURI(int index);
+
+    abstract int getAttributeCount();
+
+    abstract String getAttributePrefix(int index);
+
+    abstract String getAttributeNamespace(int index);
+
+    abstract String getAttributeLocalName(int index);
+
+    abstract QName getAttributeName(int index);
+
+    abstract boolean isAttributeSpecified(int index);
+
+    abstract String getAttributeType(int index);
+
+    abstract String getAttributeValue(int index);
+
+    abstract String getAttributeValue(String namespaceURI, String localName);
+
+    abstract NamespaceContext getNamespaceContext();
+
+    abstract String getNamespaceURI(String prefix);
+
+    /**
+     * Reads the content of a text-only element. This method has the same contract as
+     * {@link XMLStreamReader#getElementText()}, except that it is an optional operation: if the
+     * implementation can't satisfy the request, it can return <code>null</code> to let
+     * {@link PullSerializer} handle it. The reason is that skipping to the next start or end
+     * element event may require switching to another state.
+     * 
+     * @return the element text, or <code>null</code> if the request could be satisfied
+     * @throws XMLStreamException
+     */
+    abstract String getElementText() throws XMLStreamException;
+
+    abstract String getText();
+
+    abstract char[] getTextCharacters();
+
+    abstract int getTextStart();
+
+    abstract int getTextLength();
+
+    abstract int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException;
+
+    /**
+     * Check if the current event consists of all whitespace.
+     * 
+     * @return {@link Boolean#TRUE} if the current event consists of all whitespace,
+     *         {@link Boolean#FALSE} if the current event doesn't consist of all whitespace, or
+     *         <code>null</code> if the implementation has no optimized algorithm to determine if
+     *         the event consists of whitespace and {@link PullSerializer} should use a default
+     *         algorithm
+     * 
+     * @see XMLStreamReader#isWhiteSpace()
+     */
+    abstract Boolean isWhiteSpace();
+
+    abstract String getPIData();
+
+    abstract String getPITarget();
+
+    /**
+     * @see OMXMLStreamReaderEx#getDataSource()
+     */
+    abstract OMDataSource getDataSource();
+}

Propchange: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullSerializerState.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullThroughWrapper.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullThroughWrapper.java?rev=1484070&r1=1484069&r2=1484070&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullThroughWrapper.java (original)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/PullThroughWrapper.java Sat May 18 08:45:53 2013
@@ -28,9 +28,9 @@ final class PullThroughWrapper extends A
     private final StAXOMBuilder builder;
     private final OMContainer container;
 
-    PullThroughWrapper(StreamSwitch streamSwitch, XMLStreamReader nextTarget,
+    PullThroughWrapper(PullSerializer serializer, PullSerializerState nextState,
             StAXOMBuilder builder, OMContainer container, XMLStreamReader reader, int startDepth) {
-        super(streamSwitch, nextTarget, reader, startDepth);
+        super(serializer, nextState, reader, startDepth);
         this.builder = builder;
         this.container = container;
     }

Modified: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/SwitchingWrapper.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/SwitchingWrapper.java?rev=1484070&r1=1484069&r2=1484070&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/SwitchingWrapper.java (original)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/serializer/pull/SwitchingWrapper.java Sat May 18 08:45:53 2013
@@ -59,20 +59,19 @@ import org.apache.axiom.om.impl.builder.
 import org.apache.axiom.om.impl.common.IContainer;
 import org.apache.axiom.om.impl.common.OMDataSourceUtil;
 import org.apache.axiom.util.namespace.MapBasedNamespaceContext;
-import org.apache.axiom.util.stax.AbstractXMLStreamReader;
 import org.apache.axiom.util.stax.XMLStreamReaderUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 /**
- * Class used internally by {@link OMStAXWrapper}.
+ * Class used internally by {@link OMXMLStreamReaderExAdapter}.
  */
-class SwitchingWrapper extends AbstractXMLStreamReader
+class SwitchingWrapper extends PullSerializerState
     implements DataHandlerReader, CharacterDataReader, DTDReader, XMLStreamConstants {
     
     private static final Log log = LogFactory.getLog(SwitchingWrapper.class);
     
-    private final StreamSwitch streamSwitch;
+    private final PullSerializer streamSwitch;
     
     /**
      * The current node, corresponding to the current event.
@@ -160,7 +159,7 @@ class SwitchingWrapper extends AbstractX
      * @param cache
      * @param preserveNamespaceContext
      */
-    public SwitchingWrapper(StreamSwitch streamSwitch, OMXMLParserWrapper builder, OMContainer startNode,
+    public SwitchingWrapper(PullSerializer streamSwitch, OMXMLParserWrapper builder, OMContainer startNode,
                             boolean cache, boolean preserveNamespaceContext) {
         this.streamSwitch = streamSwitch;
         this.builder = builder;
@@ -177,6 +176,14 @@ class SwitchingWrapper extends AbstractX
         currentEvent = START_DOCUMENT;
     }
 
+    DTDReader getDTDReader() {
+        return this;
+    }
+
+    DataHandlerReader getDataHandlerReader() {
+        return this;
+    }
+
     public String getPrefix() {
         if (parser != null && currentEvent != END_DOCUMENT) {
             return parser.getPrefix();
@@ -261,14 +268,18 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             return parser.getTextStart();
         } else {
-            if (currentEvent == DTD || currentEvent == ENTITY_REFERENCE || !hasText()) {
-                // getTextStart() is not allowed for DTD and ENTITY_REFERENCE events; see
-                // the table in the Javadoc of XMLStreamReader
-                throw new IllegalStateException();
-            } else {
-                // getTextCharacters always returns a new char array and the start
-                // index is therefore always 0
-                return 0;
+            switch (currentEvent) {
+                case CHARACTERS:
+                case CDATA:
+                case COMMENT:
+                case SPACE:
+                    // getTextCharacters always returns a new char array and the start
+                    // index is therefore always 0
+                    return 0;
+                default:
+                    // getTextStart() is not allowed for DTD and ENTITY_REFERENCE events; see
+                    // the table in the Javadoc of XMLStreamReader
+                    throw new IllegalStateException();
             }
         }
     }
@@ -452,7 +463,7 @@ class SwitchingWrapper extends AbstractX
             }
             return uri;
         } else {
-            if (isStartElement() || isEndElement()) {
+            if (currentEvent == START_ELEMENT || currentEvent == END_ELEMENT) {
                 return getNamespace(i).getNamespaceURI();
             } else {
                 throw new IllegalStateException();
@@ -464,7 +475,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             return parser.getNamespacePrefix(i);
         } else {
-            if (isStartElement() || isEndElement()) {
+            if (currentEvent == START_ELEMENT || currentEvent == END_ELEMENT) {
                 String prefix = getNamespace(i).getPrefix();
                 return prefix.length() == 0 ? null : prefix; 
             } else {
@@ -477,7 +488,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null && currentEvent != END_DOCUMENT) {
             return parser.getNamespaceCount();
         } else {
-            if (isStartElement() || isEndElement()) {
+            if (currentEvent == START_ELEMENT || currentEvent == END_ELEMENT) {
                 loadNamespaces();
                 return namespaceCount;
             } else {
@@ -490,7 +501,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             return parser.isAttributeSpecified(i);
         } else {
-            if (isStartElement()) {
+            if (currentEvent == START_ELEMENT) {
                 // The Axiom object model doesn't store this information,
                 // but returning true is a reasonable default.
                 return true;
@@ -505,7 +516,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             return parser.getAttributeValue(i);
         } else {
-            if (isStartElement()) {
+            if (currentEvent == START_ELEMENT) {
                 return getAttribute(i).getAttributeValue();
             } else {
                 throw new IllegalStateException(
@@ -518,7 +529,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             return parser.getAttributeType(i);
         } else {
-            if (isStartElement()) {
+            if (currentEvent == START_ELEMENT) {
                 return getAttribute(i).getAttributeType();
             } else {
                 throw new IllegalStateException(
@@ -531,7 +542,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             return parser.getAttributePrefix(i);
         } else {
-            if (isStartElement()) {
+            if (currentEvent == START_ELEMENT) {
                 return getAttribute(i).getPrefix();
             } else {
                 throw new IllegalStateException(
@@ -544,7 +555,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             return parser.getAttributeLocalName(i);
         } else {
-            if (isStartElement()) {
+            if (currentEvent == START_ELEMENT) {
                 return getAttribute(i).getLocalName();
             } else {
                 throw new IllegalStateException(
@@ -557,7 +568,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             return parser.getAttributeNamespace(i);
         } else {
-            if (isStartElement()) {
+            if (currentEvent == START_ELEMENT) {
                 return getAttribute(i).getNamespaceURI();
             } else {
                 throw new IllegalStateException(
@@ -570,7 +581,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             return parser.getAttributeName(i);
         } else {
-            if (isStartElement()) {
+            if (currentEvent == START_ELEMENT) {
                 return getAttribute(i).getQName();
             } else {
                 throw new IllegalStateException(
@@ -584,7 +595,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             returnCount = parser.getAttributeCount();
         } else {
-            if (isStartElement()) {
+            if (currentEvent == START_ELEMENT) {
                 loadAttributes();
                 returnCount = attributeCount;
             } else {
@@ -601,7 +612,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             returnString = parser.getAttributeValue(s, s1);
         } else {
-            if (isStartElement()) {
+            if (currentEvent == START_ELEMENT) {
                 QName qname = new QName(s, s1);
                 OMAttribute attrib = ((OMElement) node).getAttribute(qname);
                 if (attrib != null) {
@@ -615,42 +626,8 @@ class SwitchingWrapper extends AbstractX
         return returnString;
     }
 
-    public boolean isWhiteSpace() {
-        if (parser != null) {
-            return parser.isWhiteSpace();
-        } else {
-            return super.isWhiteSpace();
-        }
-    }
-
-    public boolean isCharacters() {
-        boolean b;
-        if (parser != null) {
-            b = parser.isCharacters();
-        } else {
-            b = (currentEvent == CHARACTERS);
-        }
-        return b;
-    }
-
-    public boolean isEndElement() {
-        boolean b;
-        if (parser != null && currentEvent != END_DOCUMENT) {
-            b = parser.isEndElement();
-        } else {
-            b = (currentEvent == END_ELEMENT);
-        }
-        return b;
-    }
-
-    public boolean isStartElement() {
-        boolean b;
-        if (parser != null) {
-            b = parser.isStartElement();
-        } else {
-            b = (currentEvent == START_ELEMENT);
-        }
-        return b;
+    Boolean isWhiteSpace() {
+        return null;
     }
 
     public String getNamespaceURI(String prefix) {
@@ -658,7 +635,7 @@ class SwitchingWrapper extends AbstractX
         if (parser != null) {
             returnString = parser.getNamespaceURI(prefix);
         } else {
-            if (isStartElement() || isEndElement()) {
+            if (currentEvent == START_ELEMENT || currentEvent == END_ELEMENT) {
 
                 if (node instanceof OMElement) {
                     OMNamespace namespaceURI =
@@ -685,7 +662,7 @@ class SwitchingWrapper extends AbstractX
         } finally {
             // Note that as a side effect of this instruction, the SwitchingWrapper instance
             // will become unreachable and the parser can be GC'd or reused.
-            streamSwitch.setParent(ClosedReader.INSTANCE);
+            streamSwitch.switchState(ClosedState.INSTANCE);
         }
     }
 
@@ -795,7 +772,7 @@ class SwitchingWrapper extends AbstractX
                             while (reader.next() != START_ELEMENT) {
                                 // Just loop
                             }
-                            streamSwitch.setParent(new IncludeWrapper(streamSwitch, this, reader));
+                            streamSwitch.switchState(new IncludeWrapper(streamSwitch, this, reader));
                             node = nextNode;
                             visited = true;
                             return START_ELEMENT;
@@ -827,7 +804,7 @@ class SwitchingWrapper extends AbstractX
                         depth++;
                     }
                     PullThroughWrapper wrapper = new PullThroughWrapper(streamSwitch, this, builder, container, builder.disableCaching(), depth);
-                    streamSwitch.setParent(wrapper);
+                    streamSwitch.switchState(wrapper);
                     node = container;
                     visited = true;
                     currentEvent = wrapper.next();
@@ -1121,7 +1098,7 @@ class SwitchingWrapper extends AbstractX
     /**
      * @return OMDataSource associated with the current node or Null
      */
-    public OMDataSource getDataSource() {
+    OMDataSource getDataSource() {
         if (getEventType() != XMLStreamReader.START_ELEMENT ||
                 state != NAVIGABLE) {
             return null;