blob: a8a13fd87d4ebde53f54619b193fad53335e7972 [file] [log] [blame]
/*
* Copyright 2004,2005 The Apache Software Foundation.
* Copyright 2006 International Business Machines Corp.
*
* Licensed 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.axis2.jaxws.message.util;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
/**
* XMLStreamReaderSplitter
* An XMLStreamReaderSplitter wraps an existing XMLStreamReader and makes it
* appear that the XMLStreamReader is for a single element tree.
* Once the element tree is consumed, the getNextReader method may be called to
* get the next element tree.
*
* For example, suppose the input xml is the following:
*
* spurious text 1
* <data>
* <a>a data</a>
* <b>b data</b>
* </data>
* spurious text 2
* <data2>
* <a2>a data</a2>
* <b2>b data</b2>
* </data2>
*
* The XMLStreamReaderSplitter will only return the events for:
* <data>
* <a>a data</a>
* <b>b data</b>
* </data>
*
* Once these events are consumed, the nextStreamReader method can be called, which
* will return:
* <data2>
* <a2>a data</a2>
* <b2>b data</b2>
* </data2>
*
* Note that the spurious text and comments between the elements are ignored.
*
*/
public class XMLStreamReaderSplitter extends XMLStreamReaderFilter {
int depth = 0;
boolean start = true;
/**
* Split the input reader into multiple element trees
* @param reader XMLStreamReader
*/
public XMLStreamReaderSplitter(XMLStreamReader reader) {
super(reader);
init();
}
/**
* Reset for a new element tree
*/
private void init() {
depth = 0;
start = true;
}
public int next() throws XMLStreamException {
// If starting a new tree, ignore all of the
// events until the first start element is found.
if (start) {
start = false;
depth = 1;
int event = super.next();
while (event != START_ELEMENT) {
if (event == START_ELEMENT) {
return event;
} else if (this.hasNext()) {
event = super.next();
} else {
return event;
}
}
return event;
} else {
// Processing a tree. Adjust the
// depth as the tags are encountered.
if (depth == 0) {
// Some consumers expect an END_DOCUMENT to end their processing (some consumers will trigger the end of processing using hasNext())
return END_DOCUMENT;
}
int event = super.next();
if (event == START_ELEMENT) {
depth++;
} else if (event == END_ELEMENT) {
depth--;
}
return event;
}
}
@Override
public boolean hasNext() throws XMLStreamException {
if (depth == 0) {
// If this element tree is consumed return false
if (start) {
return super.hasNext();
} else {
return false;
}
} else {
return super.hasNext();
}
}
/**
* getStreamReader
* @return XMLStreamReader for the next element tree.
* If the prior stream reader is not consumed, this method will return null.
* (Use hasNext() to see if the prior stream reader is consumed)
* @throws XMLStreamReader
*/
public XMLStreamReader getNextReader() throws XMLStreamException {
if (!hasNext()) {
init();
if (hasNext()) {
// Return newly initialized reader
return this;
} else {
// Return null indicating no reader is available
return null;
}
} else {
// Return null if the current reader is still be read
return null;
}
}
}