Created
September 19, 2012 20:54
-
-
Save agentgt/3752190 to your computer and use it in GitHub Desktop.
Turn XML Stream into an Object Iterator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.snaphop.util; | |
import static com.google.common.base.Preconditions.checkState; | |
import java.io.Reader; | |
import java.util.Iterator; | |
import javax.xml.bind.JAXBContext; | |
import javax.xml.bind.JAXBElement; | |
import javax.xml.bind.JAXBException; | |
import javax.xml.bind.Unmarshaller; | |
import javax.xml.stream.FactoryConfigurationError; | |
import javax.xml.stream.XMLInputFactory; | |
import javax.xml.stream.XMLStreamConstants; | |
import javax.xml.stream.XMLStreamException; | |
import javax.xml.stream.XMLStreamReader; | |
import com.google.common.base.Throwables; | |
import com.google.common.collect.AbstractIterator; | |
public class XmlStreamObjectUtils { | |
public static <T> Iterator<T> readXml(final Reader reader, final Class<T> type, final String tag, boolean skipRoot) { | |
// set up a StAX reader | |
final XMLStreamReader xmlr; | |
XMLStreamReader xmlrTmp = null; | |
final Unmarshaller unmarshaller; | |
try { | |
XMLInputFactory xmlif = XMLInputFactory.newInstance(); | |
xmlrTmp = xmlif.createXMLStreamReader(reader); | |
xmlr = xmlrTmp; | |
final JAXBContext ucontext = JAXBContext.newInstance(type); | |
unmarshaller = ucontext.createUnmarshaller(); | |
while (skipRoot && xmlr.getEventType() == XMLStreamConstants.START_DOCUMENT) { | |
xmlr.nextTag(); | |
xmlr.nextTag(); | |
} | |
} catch (FactoryConfigurationError e1) { | |
close(xmlrTmp); | |
throw Throwables.propagate(e1); | |
} catch (XMLStreamException e1) { | |
close(xmlrTmp); | |
throw Throwables.propagate(e1); | |
} catch (JAXBException e1) { | |
close(xmlrTmp); | |
throw Throwables.propagate(e1); | |
} | |
return new AbstractIterator<T>() { | |
@Override | |
protected T computeNext() { | |
try { | |
final XMLStreamReader x = xmlr; | |
while (isNotValid(x, tag)) { | |
if (x.getEventType() == XMLStreamConstants.START_DOCUMENT) { | |
x.nextTag(); | |
} | |
else { | |
x.next(); | |
} | |
} | |
if (x.getEventType() == XMLStreamConstants.END_DOCUMENT) { | |
x.close(); | |
return endOfData(); | |
} | |
checkState(xmlr.getEventType() == XMLStreamConstants.START_ELEMENT, "Expected a start element."); | |
JAXBElement<T> pt = unmarshaller.unmarshal(xmlr, type); | |
return pt.getValue(); | |
} catch (XMLStreamException e) { | |
close(xmlr); | |
throw Throwables.propagate(e); | |
} catch (JAXBException e) { | |
close(xmlr); | |
throw Throwables.propagate(e); | |
} | |
} | |
private boolean isNotValid(final XMLStreamReader xmlr, final String tag) { | |
boolean hasTag = (xmlr.getEventType() == XMLStreamConstants.START_ELEMENT | |
&& (tag == null || tag.equals(xmlr.getLocation()))); | |
return ! hasTag && xmlr.getEventType() != XMLStreamConstants.START_ELEMENT | |
&& xmlr.getEventType() != XMLStreamConstants.END_DOCUMENT; | |
} | |
@Override | |
protected void finalize() throws Throwable { | |
super.finalize(); | |
close(xmlr); | |
} | |
}; | |
} | |
public static void close(XMLStreamReader reader) { | |
if (reader != null) { | |
try { | |
reader.close(); | |
} catch (XMLStreamException e) { | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment