Author: scheu
Date: Tue Jan 19 22:46:32 2010
New Revision: 900993
URL: http://svn.apache.org/viewvc?rev=900993&view=rev
Log:
WSCOMMONS-518
Contributor: Rich Scheuerle
Analysis: Doug Larson
Summary of Problem:
The new XMLStreamReader wrappers and delegates in Axiom prevent consumers from
directly accessing the original
parser. This has caused regressions for some users.
Summary of Solution:
The XMLStreamReader wrappers and delegates remain intact. Some of them have
been marked with a new marker interface, XMLStreamReaderContainer. New utility
methods are added to XMLStreamReaderUtils to allow a consumer to access the
original XMLStreamReader.
Tests are added to verify the function.
Note that an OMStAXWRapper is not an XMLStreamReaderContainer. An
OMStaXWrapper actually wraps a OM tree and
adapts it to an XMLStreamReader interface (versus wrapping an actual live
parser).
Added:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/wrapper/XMLStreamReaderContainer.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/om/impl/builder/SafeXMLStreamReader.java
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamReaderUtils.java
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/wrapper/XMLStreamReaderWrapper.java
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReader.java
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPEncodingStreamReader.java
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/mtom/MTOMStAXSOAPModelBuilderTest.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=900993&r1=900992&r2=900993&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
Tue Jan 19 22:46:32 2010
@@ -41,6 +41,8 @@
/**
* {...@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).
*/
public class OMStAXWrapper extends StreamReaderDelegate implements
OMXMLStreamReader {
private static final Log log = LogFactory.getLog(OMStAXWrapper.class);
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SafeXMLStreamReader.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SafeXMLStreamReader.java?rev=900993&r1=900992&r2=900993&view=diff
==============================================================================
---
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SafeXMLStreamReader.java
(original)
+++
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SafeXMLStreamReader.java
Tue Jan 19 22:46:32 2010
@@ -23,6 +23,8 @@
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
+import org.apache.axiom.util.stax.wrapper.XMLStreamReaderContainer;
+
/**
* XMLStreamReader wrapper that prevents access to the underlying parser
* after the first error occurs.
@@ -55,7 +57,7 @@
* to {...@link XMLStreamReader#next()} and similar methods on the underlying
parser.
* Any attempt to do so will immediately result in an error.
*/
-public class SafeXMLStreamReader extends StreamReaderDelegate {
+public class SafeXMLStreamReader extends StreamReaderDelegate implements
XMLStreamReaderContainer {
private boolean parserError;
public SafeXMLStreamReader(XMLStreamReader reader) {
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamReaderUtils.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamReaderUtils.java?rev=900993&r1=900992&r2=900993&view=diff
==============================================================================
---
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamReaderUtils.java
(original)
+++
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/XMLStreamReaderUtils.java
Tue Jan 19 22:46:32 2010
@@ -26,12 +26,19 @@
import org.apache.axiom.attachments.ByteArrayDataSource;
import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
+import org.apache.axiom.om.OMAttachmentAccessor;
import org.apache.axiom.om.util.Base64;
+import org.apache.axiom.util.stax.wrapper.XMLStreamReaderContainer;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* Contains utility methods to work with {...@link XMLStreamReader} objects.
*/
public class XMLStreamReaderUtils {
+
+ private static Log log = LogFactory.getLog(XMLStreamReaderUtils.class);
+
/**
* Get the {...@link DataHandlerReader} extension from a given {...@link
XMLStreamReader}.
*
@@ -108,4 +115,60 @@
}
return new DataHandler(new ByteArrayDataSource(Base64.decode(base64)));
}
+
+ /**
+ * getOriginalXMLStreamReader
+ * Searches the wrapper and delegate classes to find the original
XMLStreamReader
+ * This method should only be used when a consumer of Axiom really needs
to
+ * access the original stream reader.
+ * @param parser XMLStreamReader used by Axiom
+ * @return original parser
+ */
+ public static XMLStreamReader getOriginalXMLStreamReader(XMLStreamReader
parser) {
+ if (log.isDebugEnabled()) {
+ String clsName = (parser != null) ? parser.getClass().toString() :
"null";
+ log.debug("Entry getOriginalXMLStreamReader: " + clsName);
+ }
+ while (parser instanceof XMLStreamReaderContainer) {
+ parser = ((XMLStreamReaderContainer) parser).getParent();
+ if (log.isDebugEnabled()) {
+ String clsName = (parser != null) ?
parser.getClass().toString() : "null";
+ log.debug(" parent: " + clsName);
+ }
+ }
+ if (log.isDebugEnabled()) {
+ String clsName = (parser != null) ? parser.getClass().toString() :
"null";
+ log.debug("Exit getOriginalXMLStreamReader: " + clsName);
+ }
+ return parser;
+ }
+
+ /**
+ * Searches the wrapper and delegate classes to find an XMLStreamReader
+ * that implements the OMAttachmentAccessor
+ * @param parser
+ * @return XMLStreamREader that implements OMAttachmentAccessor or null
+ */
+ public static XMLStreamReader
getOMAttachmentAccessorXMLStreamReader(XMLStreamReader parser) {
+ if (log.isDebugEnabled()) {
+ String clsName = (parser != null) ? parser.getClass().toString() :
"null";
+ log.debug("Entry getOMAttachmentAccessorXMLStreamReader: " +
clsName);
+ }
+ while (!(parser instanceof OMAttachmentAccessor) &&
+ (parser instanceof XMLStreamReaderContainer)) {
+ parser = ((XMLStreamReaderContainer) parser).getParent();
+ if (log.isDebugEnabled()) {
+ String clsName = (parser != null) ?
parser.getClass().toString() : "null";
+ log.debug(" parent: " + clsName);
+ }
+ }
+ if (!(parser instanceof OMAttachmentAccessor)) {
+ parser = null;
+ }
+ if (log.isDebugEnabled()) {
+ String clsName = (parser != null) ? parser.getClass().toString() :
"null";
+ log.debug("Exit getOMAttachmentAccessorXMLStreamReader: " +
clsName);
+ }
+ return parser;
+ }
}
Added:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/wrapper/XMLStreamReaderContainer.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/wrapper/XMLStreamReaderContainer.java?rev=900993&view=auto
==============================================================================
---
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/wrapper/XMLStreamReaderContainer.java
(added)
+++
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/wrapper/XMLStreamReaderContainer.java
Tue Jan 19 22:46:32 2010
@@ -0,0 +1,37 @@
+/*
+ * 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.util.stax.wrapper;
+
+import javax.xml.stream.XMLStreamReader;
+
+/**
+ * Marker interface for Axiom XMLStreamReader classes that
+ * wrap or delegate to another (parent) XMLStreamReader.
+ *
+ * The marker interface is necessary so that consumers
+ * can access the original parser.
+ * @see XMLStreamReaderUtils
+ *
+ * Note that the only the getParent() method is applicable.
+ * Please do not add a setParent() method since that would
+ * violate the immutable characteristic of the XMLStreamReaderWrapper
+ */
+public interface XMLStreamReaderContainer {
+ XMLStreamReader getParent();
+}
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/wrapper/XMLStreamReaderWrapper.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/wrapper/XMLStreamReaderWrapper.java?rev=900993&r1=900992&r2=900993&view=diff
==============================================================================
---
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/wrapper/XMLStreamReaderWrapper.java
(original)
+++
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/wrapper/XMLStreamReaderWrapper.java
Tue Jan 19 22:46:32 2010
@@ -31,7 +31,7 @@
* similar to {...@link javax.xml.stream.util.StreamReaderDelegate}, with the
difference that it is
* immutable.
*/
-public class XMLStreamReaderWrapper implements XMLStreamReader {
+public class XMLStreamReaderWrapper implements XMLStreamReader,
XMLStreamReaderContainer {
private final XMLStreamReader parent;
/**
@@ -42,6 +42,15 @@
public XMLStreamReaderWrapper(XMLStreamReader parent) {
this.parent = parent;
}
+
+ /**
+ * Get Parent
+ * Note that setParent is intentionally omitted. XMLStreamReaderWrapper
is immutable.
+ * @return XMLStreamReader parent
+ */
+ public XMLStreamReader getParent() {
+ return parent;
+ }
public void close() throws XMLStreamException {
parent.close();
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReader.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReader.java?rev=900993&r1=900992&r2=900993&view=diff
==============================================================================
---
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReader.java
(original)
+++
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/util/stax/xop/XOPDecodingStreamReader.java
Tue Jan 19 22:46:32 2010
@@ -35,6 +35,7 @@
import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
import org.apache.axiom.om.util.StAXUtils;
import org.apache.axiom.util.base64.Base64Utils;
+import org.apache.axiom.util.stax.wrapper.XMLStreamReaderContainer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -56,7 +57,8 @@
* {...@link DataHandlerReader#getDataHandlerProvider()}, then the {...@link
MimePartProvider} will only
* be invoked when {...@link DataHandlerProvider#getDataHandler()} is called.
*/
-public class XOPDecodingStreamReader extends StreamReaderDelegate implements
XMLStreamReader, DataHandlerReader {
+public class XOPDecodingStreamReader extends StreamReaderDelegate
+ implements XMLStreamReader, DataHandlerReader, XMLStreamReaderContainer {
private static final String SOLE_CHILD_MSG =
"Expected xop:Include as the sole child of an element information
item (see section " +
"3.2 of http://www.w3.org/TR/xop10/)";
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=900993&r1=900992&r2=900993&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
Tue Jan 19 22:46:32 2010
@@ -33,6 +33,7 @@
import javax.xml.stream.XMLStreamReader;
import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
+import org.apache.axiom.util.stax.wrapper.XMLStreamReaderContainer;
/**
* {...@link XMLStreamReader} wrapper that encodes XOP. It assumes that the
underlying reader
@@ -52,7 +53,8 @@
* This class defers loading of {...@link DataHandler} objects until {...@link
#getDataHandler(String)} is
* called, except if this is not supported by the underlying stream.
*/
-public class XOPEncodingStreamReader extends XOPEncodingStreamWrapper
implements XMLStreamReader {
+public class XOPEncodingStreamReader extends XOPEncodingStreamWrapper
+ implements XMLStreamReader, XMLStreamReaderContainer {
/**
* Wrapper that adds the XOP namespace to another namespace context.
*/
@@ -530,4 +532,8 @@
default: return parent.isEndElement();
}
}
+
+ public XMLStreamReader getParent() {
+ return parent;
+ }
}
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/mtom/MTOMStAXSOAPModelBuilderTest.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/mtom/MTOMStAXSOAPModelBuilderTest.java?rev=900993&r1=900992&r2=900993&view=diff
==============================================================================
---
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/mtom/MTOMStAXSOAPModelBuilderTest.java
(original)
+++
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/mtom/MTOMStAXSOAPModelBuilderTest.java
Tue Jan 19 22:46:32 2010
@@ -28,10 +28,13 @@
import org.apache.axiom.om.OMOutputFormat;
import org.apache.axiom.om.OMText;
import org.apache.axiom.om.OMXMLStreamReader;
+import org.apache.axiom.om.impl.OMStAXWrapper;
+import org.apache.axiom.om.impl.builder.StAXBuilder;
import org.apache.axiom.om.impl.traverse.OMDescendantsIterator;
import org.apache.axiom.om.util.StAXUtils;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.impl.builder.MTOMStAXSOAPModelBuilder;
+import org.apache.axiom.util.stax.XMLStreamReaderUtils;
import javax.activation.DataHandler;
import javax.xml.namespace.QName;
@@ -79,6 +82,7 @@
return createBuilderForTestMTOMMessage().getDocumentElement();
}
+
private void checkSerialization(OMElement root, boolean optimize) throws
Exception {
OMOutputFormat format = new OMOutputFormat();
format.setDoOptimize(optimize);
@@ -95,6 +99,45 @@
}
}
+ public void testAccessToParser() throws Exception {
+ OMElement root = createTestMTOMMessage();
+ StAXBuilder builder = (StAXBuilder) root.getBuilder();
+ // Disable caching so that the reader can be accessed.
+ builder.setCache(false);
+ XMLStreamReader reader = (XMLStreamReader) builder.getParser();
+
+ XMLStreamReader original =
XMLStreamReaderUtils.getOriginalXMLStreamReader(reader);
+
+ // The streaming parser is wrapped by a SafeXMLStreamReader and
dialect readers.
+ // Thus the reader and original readers will not be the same.
+ assertTrue(reader != original);
+
+ // The streaming parser will not have access to the attachments. Thus
this will
+ // return null
+ XMLStreamReader attachmentAccessor =
+
XMLStreamReaderUtils.getOMAttachmentAccessorXMLStreamReader(reader);
+
+ assertTrue(attachmentAccessor == null);
+
+ }
+
+ public void testAccessToCachedParser() throws Exception {
+ OMElement root = createTestMTOMMessage();
+ XMLStreamReader reader = root.getXMLStreamReader(true);
+
+ XMLStreamReader original =
XMLStreamReaderUtils.getOriginalXMLStreamReader(reader);
+
+ // The caching parser will be an OMStaXWrapper.
+ assertTrue(original instanceof OMStAXWrapper);
+
+ XMLStreamReader attachmentAccessor =
+
XMLStreamReaderUtils.getOMAttachmentAccessorXMLStreamReader(reader);
+
+ // Thus the attachmentAccessor should also be the OMStaXWrapper
+ assertTrue(attachmentAccessor instanceof OMStAXWrapper);
+
+ }
+
public void testCreateOMElement() throws Exception {
OMElement root = createTestMTOMMessage();
OMElement body = (OMElement) root.getFirstOMChild();