[ http://issues.apache.org/jira/browse/AXIS2-919?page=all ]
Deepal Jayasinghe reassigned AXIS2-919:
---------------------------------------
Assignee: Eran Chinthaka
> Unable to print out entire SOAP message: bug in OMElement.serialize()
> ---------------------------------------------------------------------
>
> Key: AXIS2-919
> URL: http://issues.apache.org/jira/browse/AXIS2-919
> Project: Apache Axis 2.0 (Axis2)
> Issue Type: Bug
> Components: core, om
> Affects Versions: 1.0
> Reporter: Derek Foster
> Assigned To: Eran Chinthaka
>
> I was attempting, inside an XMLBeans-generated service method, to print out
> the entire SOAP message to a log file. Towards that end, I tried to execute
> the following code:
> final StringWriter writer = new StringWriter();
> messageContext.getEnvelope().serialize(writer);
> System.out.println(writer.toString());
> However, I was surprised to get the following exception resulting from this:
> org.apache.axiom.om.OMException
> at
> org.apache.axiom.om.impl.llom.OMElementImpl.getNextOMSibling(OMElementImpl.java:266)
> at
> org.apache.axiom.om.impl.traverse.OMChildrenIterator.next(OMChildrenIterator.java:111)
> at
> org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:771)
> at
> org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvelopeImpl.java:177)
> at
> org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:756)
> at
> org.apache.axiom.om.impl.llom.OMNodeImpl.serialize(OMNodeImpl.java:310)
> at
> org.apache.axiom.om.impl.llom.OMNodeImpl.serialize(OMNodeImpl.java:352)
> ...
> The cause of the problem appears to be the fact that the SOAP envelope is a
> top-level XML object. Thus, the item immediately following it is a
> DOCUMENT_END. The OMElementImpl.internalSerialize(XMLStreamWriter, boolean
> cache) method contains the following code:
> Iterator children = this.getChildren();
> while (children.hasNext()) {
> ((OMNodeEx) children.next()).internalSerialize(writer);
> which seems plausible. However, the iterator that is returned is of type
> OMChildrenIterator. Its hasNext method looks like this:
> /**
> * Returns <tt>true</tt> if the iteration has more elements. (In other
> * words, returns <tt>true</tt> if <tt>next</tt> would return an element
> * rather than throwing an exception.)
> *
> * @return Returns <tt>true</tt> if the iterator has more elements.
> */
> public boolean hasNext() {
> return (currentChild != null);
> }
> but its next() method looks like this:
> /**
> * Returns the next element in the iteration.
> *
> * @return Returns the next element in the iteration.
> * @throws java.util.NoSuchElementException
> * iteration has no more elements.
> */
> public Object next() {
> nextCalled = true;
> removeCalled = false;
> if (hasNext()) {
> lastChild = currentChild;
> currentChild = currentChild.getNextOMSibling();
> return lastChild;
> }
> return null;
> }
> which is a problem, because currentChild.getNextOMSibling() looks like this:
> /**
> * Gets the next sibling. This can be an OMAttribute or OMText or
> * OMELement for others.
> *
> * @throws OMException
> */
> public OMNode getNextOMSibling() throws OMException {
> while (!done) {
> int token = builder.next();
> if (token == XMLStreamConstants.END_DOCUMENT) {
> throw new OMException();
> }
> }
> return super.getNextOMSibling();
> }
> which will under some circumstances throw an OMException, which is not in the
> contract of the iterator's next() method to throw.
> Thus, iterator.hasNext() is returning true, implying that there is a next
> element, but when next() is actually called, the iterator discovers that it
> has reached the end of the document, and that therefore there really is no
> next element. It therefore throws an OMException.
> Firstly, if the next() method is going to be implemented this way, then
> hasNext() should perform enough lookahead on the document to detect that the
> next item in the input stream is indeed a END_DOCUMENT, and should therefore
> return false, since under these circumstances there truly isn't a next
> element (and calling next() would therefore always throw an OMException).
> That way, when the end of the document is hit, the serialize method will
> simply stop and return its results rather than trying to advance past the end
> of the document as it does now.
> Secondly, this OMException really should have some meaningful error text in
> it, such as "Can't call 'next()' on an iterator which is positioned at
> element 'foo' which is the last element in the document" or even better,
> "Can't call next() when hasNext() returns false" (see below). I can't think
> of any cases in typical library code where it is desirable to throw
> exceptions that don't have any message text. This is really unpleasant for
> anybody that is trying to debug a problem. I would encourage someone to do a
> search through the source code for "throw new OMException()" and add an
> explanatory error message wherever one is found.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]