com.giffing.easyxml.reader.Parser Maven / Gradle / Ivy
package com.giffing.easyxml.reader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.commons.lang3.StringUtils;
import com.giffing.easyxml.context.ParseContext;
import com.giffing.easyxml.context.TransformContext;
import com.giffing.easyxml.reader.item.ItemReader;
import com.giffing.easyxml.stax.reader.StaxReader;
import com.giffing.easyxml.stax.reader.context.StaxTransformerResult;
public class Parser implements Iterable {
private XMLInputFactory xif = XMLInputFactory.newInstance();
private XMLStreamReader streamReader = null;
private InputStream inputStream = null;
private List currentElementPath = new ArrayList<>();
private List extends Reader> readers = new ArrayList<>();
private ParseContext context;
private Reader currentReader;
private ItemReader currentItemReader = null;
private List extends ItemReader> staxItemReaders = new ArrayList<>();
public Parser(List extends Reader> readers, List extends ItemReader> staxItemReaders, ParseContext context) {
this.readers = readers;
this.staxItemReaders = staxItemReaders;
this.context = context;
}
public void setParseContext(ParseContext context) {
this.context = context;
}
public R readNext() {
return currentItemReader.read(currentReader.transform(
new TransformContext(streamReader, currentItemReader))
.getContent());
}
public boolean hasNext() {
if (streamReader == null) {
doOpen();
}
try {
while (streamReader.hasNext()) {
if (streamReader.isEndElement()) {
if (currentElementPath.size() > 0) {
int lastElementIndex = currentElementPath.size() - 1;
if (currentElementPath.get(lastElementIndex).equals(streamReader.getLocalName())) {
currentElementPath.remove(lastElementIndex);
}
}
}
if (streamReader.isStartElement()) {
String localName = streamReader.getLocalName();
currentElementPath.add(localName);
String path = StringUtils.join(currentElementPath, "/");
context.setPath(path);
for (ItemReader staxItemReader : staxItemReaders) {
if(staxItemReader.shouldHandle(context)) {
staxItemReader.read(new StaxTransformerResult(streamReader).getContent());
}
}
for (Reader reader : readers) {
for (ItemReader itemReader : reader.getItemReaders()) {
if ((itemReader).shouldHandle(context)) {
if (currentElementPath.size() > 0) {
currentElementPath.remove(currentElementPath.size() - 1);
}
currentReader = reader;
currentItemReader = itemReader;
return true;
}
}
}
}
streamReader.next();
}
} catch (XMLStreamException e) {
throw new IllegalStateException(e);
}
return false;
}
public void close() {
if (streamReader != null) {
try {
streamReader.close();
} catch (XMLStreamException e) {
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
private void doOpen() {
try {
streamReader = xif.createXMLStreamReader(inputStream, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
@Override
public Iterator iterator() {
return new Iterator() {
@Override
public boolean hasNext() {
return Parser.this.hasNext();
}
@Override
public R next() {
return Parser.this.readNext();
}
};
}
}