// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.opendata.core.io.archive; import static org.openstreetmap.josm.tools.I18n.tr; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.xml.stream.FactoryConfigurationError; import javax.xml.stream.XMLStreamException; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.gui.progress.ProgressMonitor; import org.openstreetmap.josm.io.IllegalDataException; import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler; public class ZipReader extends ArchiveReader { private final ZipInputStream zis; private ZipEntry entry; public ZipReader(InputStream in, AbstractDataSetHandler handler, boolean promptUser) { super(handler, handler != null ? handler.getArchiveHandler() : null, promptUser); this.zis = in instanceof ZipInputStream ? (ZipInputStream) in : new ZipInputStream(in); } public static DataSet parseDataSet(InputStream in, AbstractDataSetHandler handler, ProgressMonitor instance, boolean promptUser) throws IOException, XMLStreamException, FactoryConfigurationError, IllegalDataException { return new ZipReader(in, handler, promptUser).parseDoc(instance); } public static Map<File, DataSet> parseDataSets(InputStream in, AbstractDataSetHandler handler, ProgressMonitor instance, boolean promptUser) throws IOException, XMLStreamException, FactoryConfigurationError, IllegalDataException { return new ZipReader(in, handler, promptUser).parseDocs(instance); } @Override protected void extractArchive(final File temp, final List<File> candidates) throws IOException, FileNotFoundException { while ((entry = zis.getNextEntry()) != null) { if (Main.isDebugEnabled()) { Main.debug("Extracting "+entry.getName()); } File file = new File(temp + File.separator + entry.getName()); File parent = file.getParentFile(); if (parent != null && !parent.exists()) { parent.mkdirs(); } if (file.exists() && !file.delete()) { throw new IOException("Could not delete temp file/dir: " + file.getAbsolutePath()); } if (!entry.isDirectory()) { if (!file.createNewFile()) { throw new IOException("Could not create temp file: " + file.getAbsolutePath()); } // Write temp file try (FileOutputStream fos = new FileOutputStream(file)) { byte[] buffer = new byte[8192]; int count = 0; while ((count = zis.read(buffer, 0, buffer.length)) > 0) { fos.write(buffer, 0, count); } } // Allow handler to perform specific treatments (for example, fix invalid .prj files) if (archiveHandler != null) { archiveHandler.notifyTempFileWritten(file); } // Set last modification date long time = entry.getTime(); if (time > -1) { file.setLastModified(time); } lookForCandidate(entry.getName(), candidates, file); } else if (!file.mkdir()) { throw new IOException("Could not create temp dir: " + file.getAbsolutePath()); } } } @Override protected String getTaskMessage() { return tr("Reading Zip file..."); } }