/* | |
* 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; | |
} | |
} | |
} |