Author: veithen
Date: Sun May 23 07:25:57 2010
New Revision: 947371
URL: http://svn.apache.org/viewvc?rev=947371&view=rev
Log:
Eliminated SafeXMLStreamReader (see WSCOMMONS-372) and integrated its code into
StAX(OM)Builder.
Reason: Using an XMLStreamReader wrapper is easy and robust, but has two issues:
* It is not easy to distinguish between exceptions caused by parsing errors and
exceptions caused by incorrect invocations of the reader.
* The wrapper sometimes gets in the way of other features; see WSCOMMONS-518
and WSCOMMONS-540.
Removed:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SafeXMLStreamReader.java
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXBuilder.java
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXBuilder.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXBuilder.java?rev=947371&r1=947370&r2=947371&view=diff
==============================================================================
---
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXBuilder.java
(original)
+++
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXBuilder.java
Sun May 23 07:25:57 2010
@@ -106,6 +106,12 @@ public abstract class StAXBuilder implem
protected int elementLevel = 0;
/**
+ * Stores exceptions thrown by the parser. Used to avoid accessing the
parser
+ * again after is has thrown a parse exception.
+ */
+ protected Exception parserException;
+
+ /**
* Constructor StAXBuilder.
* This constructor is used if the parser is at the beginning
(START_DOCUMENT).
*
@@ -146,7 +152,7 @@ public abstract class StAXBuilder implem
((BuilderAwareReader) parser).setBuilder(this);
}
dataHandlerReader =
DataHandlerReaderUtils.getDataHandlerReader(parser);
- this.parser = new SafeXMLStreamReader(parser);
+ this.parser = parser;
}
/**
@@ -276,7 +282,16 @@ public abstract class StAXBuilder implem
omContainer.addChild(text);
return text;
} else {
- return omfactory.createOMText(omContainer, parser.getText(),
textType);
+ // Some parsers (like Woodstox) parse text nodes lazily and may
throw a
+ // RuntimeException in getText()
+ String text;
+ try {
+ text = parser.getText();
+ } catch (RuntimeException ex) {
+ parserException = ex;
+ throw ex;
+ }
+ return omfactory.createOMText(omContainer, text, textType);
}
}
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java?rev=947371&r1=947370&r2=947371&view=diff
==============================================================================
---
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
(original)
+++
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
Sun May 23 07:25:57 2010
@@ -52,6 +52,32 @@ import java.io.InputStream;
* This class supports the {...@link XMLStreamReader} extension defined by
* {...@link org.apache.axiom.ext.stax.datahandler.DataHandlerReader} as well
as the legacy extension mechanism
* defined in the documentation of {...@link DataHandlerReaderUtils}.
+ * <h3>Error handling</h3>
+ * Usually, code that uses StAX directly just stops processing of an XML
document
+ * once the first parsing error has been reported. However, since Axiom
+ * uses deferred parsing, and client code accesses the XML infoset using
+ * an object model, things are more complicated. Indeed, if the XML
+ * document is not well formed, the corresponding error might be reported
+ * as a runtime exception by any call to a method of an OM node.
+ * <p>
+ * Typically the client code will have some error handling that will intercept
+ * runtime exceptions and take appropriate action. Very often this error
handling
+ * code might want to access the object model again, for example to log the
request that caused the
+ * failure. This causes no problem except if the runtime exception was caused
by a
+ * parsing error, in which case Axiom would again try to pull events from the
parser.
+ * <p>
+ * This would lead to a situation where Axiom accesses a parser that has
reported a parsing
+ * error before. While one would expect that after a first error reported by
the parser, all
+ * subsequent invocations of the parser will fail, this is not the case for
all parsers
+ * (at least not in all situations). Instead, the parser might be left in an
inconsistent
+ * state after the error. E.g. WSCOMMONS-372 describes a case where Woodstox
+ * encounters an error in {...@link XMLStreamReader#getText()} but continues
to return
+ * (incorrect) events afterwards. The explanation for this behaviour might be
that
+ * the situation described here is quite uncommon when StAX is used directly
(i.e. not through
+ * Axiom).
+ * <p>
+ * To avoid this, the builder remembers exceptions thrown by the parser and
rethrows
+ * them during a call to {...@link #next()}.
*/
public class StAXOMBuilder extends StAXBuilder {
/** Field document */
@@ -633,7 +659,21 @@ public class StAXOMBuilder extends StAXB
lookAheadToken = -1; // Reset
return token;
} else {
- return parser.next();
+ if (parserException != null) {
+ log.warn("Attempt to access a parser that has thrown a parse
exception before; " +
+ "rethrowing the original exception.");
+ if (parserException instanceof XMLStreamException) {
+ throw (XMLStreamException)parserException;
+ } else {
+ throw (RuntimeException)parserException;
+ }
+ }
+ try {
+ return parser.next();
+ } catch (XMLStreamException ex) {
+ parserException = ex;
+ throw ex;
+ }
}
}