001package edu.pdx.cs410J.grader; 002 003import com.google.common.io.ByteStreams; 004import org.slf4j.Logger; 005import org.slf4j.LoggerFactory; 006 007import java.io.*; 008import java.util.Date; 009import java.util.Map; 010import java.util.jar.Attributes; 011import java.util.jar.JarFile; 012import java.util.jar.Manifest; 013import java.util.zip.ZipEntry; 014import java.util.zip.ZipOutputStream; 015 016public class ZipFileMaker { 017 protected static final Logger logger = LoggerFactory.getLogger("edu.pdx.cs410J.grader"); 018 019 protected final Map<Attributes.Name, String> manifestEntries; 020 private OutputStream zipStream; 021 022 public ZipFileMaker(File zipFile, Map<Attributes.Name, String> manifestEntries) throws FileNotFoundException { 023 this(new FileOutputStream(zipFile), manifestEntries); 024 } 025 026 public ZipFileMaker(OutputStream zipStream, Map<Attributes.Name, String> manifestEntries) { 027 this.manifestEntries = manifestEntries; 028 this.zipStream = zipStream; 029 } 030 031 protected void makeZipFile(Map<ZipEntry, InputStream> zipFileEntries) throws IOException { 032 ZipOutputStream zos = new ZipOutputStream(zipStream); 033 zos.setMethod(ZipOutputStream.DEFLATED); 034 035 // Create a Manifest for the Zip file containing the name of the 036 // author (userName) and a version that is based on the current 037 // date/time. 038 writeManifestAsEntryInZipFile(zos); 039 040 // Add the source files to the Zip 041 for (Map.Entry<ZipEntry, InputStream> entry : zipFileEntries.entrySet()) { 042 // Add the entry to the ZIP file 043 zos.putNextEntry(entry.getKey()); 044 045 ByteStreams.copy(entry.getValue(), zos); 046 047 zos.closeEntry(); 048 } 049 050 zos.close(); 051 } 052 053 private void writeManifestAsEntryInZipFile(ZipOutputStream zos) throws IOException { 054 Manifest manifest = new Manifest(); 055 addEntriesToMainManifest(manifest); 056 057 String entryName = JarFile.MANIFEST_NAME; 058 059 logger.debug("Adding " + entryName + " to zip"); 060 ZipEntry entry = new ZipEntry(entryName); 061 entry.setTime(System.currentTimeMillis()); 062 entry.setMethod(ZipEntry.DEFLATED); 063 064 zos.putNextEntry(entry); 065 manifest.write(new BufferedOutputStream(zos)); 066 zos.closeEntry(); 067 } 068 069 private void addEntriesToMainManifest(Manifest manifest) { 070 Attributes attrs = manifest.getMainAttributes(); 071 072 // If a manifest doesn't have a version, the other attributes won't get written out. Lame. 073 attrs.put(Attributes.Name.MANIFEST_VERSION, new Date().toString()); 074 075 for (Map.Entry<Attributes.Name, String> entry : this.manifestEntries.entrySet()) { 076 attrs.put(entry.getKey(), entry.getValue()); 077 } 078 } 079}