package org.openlca.io.ecospold2.input;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spold2.DataSet;
import spold2.EcoSpold2;
class DataSetIterator implements Iterator<DataSet>, Closeable {
private Logger log = LoggerFactory.getLogger(getClass());
private DataSet next;
private File[] files;
private int currentFile;
private ZipFile zipFile;
private int currentZipEntry;
private ZipEntry[] zipEntries;
public DataSetIterator(File[] files) {
log.trace("initialize data set iterator");
this.files = files;
currentFile = 0;
moveNext();
}
@Override
public void close() throws IOException {
next = null;
files = null;
closeZip();
}
@Override
public void remove() {
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public DataSet next() {
DataSet current = next;
moveNext();
return current;
}
private void moveNext() {
if (zipFile != null) {
moveNextInZip();
return;
}
next = null;
if (files == null || currentFile >= files.length) {
log.trace("no more files");
return;
}
log.trace("move data set pointer in files");
File file = files[currentFile];
currentFile++;
if (isSpoldFile(file.getName()))
nextSpold(file);
else if (isZip(file)) {
openZip(file);
moveNextInZip();
} else {
log.trace("ignore file {}", file);
moveNext();
}
}
private void nextSpold(File file) {
try {
next = EcoSpold2.read(file);
} catch (Exception e) {
log.error("failed to read spold file " + file, e);
moveNext();
}
}
private void openZip(File file) {
log.trace("open zip file {}", file);
try {
currentZipEntry = 0;
zipFile = new ZipFile(file);
Enumeration<? extends ZipEntry> entries = zipFile.entries();
List<ZipEntry> spoldEntries = new ArrayList<>();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (entry.isDirectory())
continue;
if (isSpoldFile(entry.getName()))
spoldEntries.add(entry);
}
this.zipEntries = spoldEntries.toArray(new ZipEntry[spoldEntries
.size()]);
} catch (Exception e) {
log.error("failed to open Zip file " + file, e);
closeZip();
}
}
private void moveNextInZip() {
next = null;
if (zipFile == null || zipEntries == null
|| currentZipEntry >= zipEntries.length) {
log.trace("no more zip entries");
moveNext();
}
log.trace("move data set pointer in zip entries");
ZipEntry entry = zipEntries[currentZipEntry];
currentZipEntry++;
try {
next = EcoSpold2.read(zipFile.getInputStream(entry));
if (currentZipEntry >= zipEntries.length)
closeZip();
} catch (Exception e) {
log.error("failed to open zip entry", e);
}
}
private void closeZip() {
if (zipFile == null)
return;
try {
zipFile.close();
} catch (Exception e) {
log.error("failed to close zip file " + zipFile, e);
} finally {
zipFile = null;
zipEntries = null;
currentZipEntry = 0;
}
}
private boolean isSpoldFile(String name) {
if (name == null)
return false;
return name.toLowerCase().endsWith(".spold");
}
private boolean isZip(File file) {
if (file == null)
return false;
return file.getName().toLowerCase().endsWith(".zip");
}
}