Throw exception on empty/invalid zip

-removed duplicate zips file
-removed unused copy/paste code

Bug: 507305
Change-Id: I11e036d2c63c5d109404191aa0655668413f78cc
Signed-off-by: Daniel Haftstein <haftsteind@gmail.com>
diff --git a/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerProblemsHistory.java b/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerProblemsHistory.java
index 2dc1e4a..22ca193 100644
--- a/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerProblemsHistory.java
+++ b/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerProblemsHistory.java
@@ -52,6 +52,7 @@
 import org.eclipse.epp.internal.logging.aeri.ide.l10n.LogMessages;
 import org.eclipse.epp.internal.logging.aeri.ide.l10n.Messages;
 import org.eclipse.epp.internal.logging.aeri.ide.utils.Formats;
+import org.eclipse.epp.internal.logging.aeri.ide.utils.Zips;
 import org.eclipse.epp.logging.aeri.core.ILink;
 import org.eclipse.epp.logging.aeri.core.IModelFactory;
 import org.eclipse.epp.logging.aeri.core.IProblemState;
diff --git a/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/Zips.java b/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/Zips.java
deleted file mode 100644
index 259cf35..0000000
--- a/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/Zips.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * Copyright (c) 2015 Codetrails GmbH.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package org.eclipse.epp.internal.logging.aeri.ide.server.mars;
-
-import static com.google.common.base.Optional.*;
-import static com.google.common.io.ByteStreams.toByteArray;
-import static com.google.common.io.Files.newInputStreamSupplier;
-import static org.apache.commons.io.filefilter.DirectoryFileFilter.DIRECTORY;
-import static org.apache.commons.io.filefilter.FileFileFilter.FILE;
-import static org.apache.commons.lang3.StringUtils.removeStart;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.jar.JarFile;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
-
-import org.apache.commons.io.FileUtils;
-import org.eclipse.jdt.annotation.Nullable;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.base.Throwables;
-import com.google.common.io.Closeables;
-import com.google.common.io.FileWriteMode;
-import com.google.common.io.Files;
-import com.google.common.io.OutputSupplier;
-
-public class Zips {
-
-    public static ZipFile NULL() {
-        try {
-            File tmp = File.createTempFile("recommenders_null_zip", ".zip"); //$NON-NLS-1$ //$NON-NLS-2$
-            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(tmp));
-            zos.putNextEntry(new ZipEntry("/")); //$NON-NLS-1$
-            zos.closeEntry();
-            zos.close();
-            return new ZipFile(tmp);
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    /**
-     * This abstraction is used for testing.
-     */
-    @VisibleForTesting
-    public interface IFileToJarFileConverter {
-        Optional<JarFile> createJarFile(File file);
-    }
-
-    public static class DefaultJarFileConverter implements IFileToJarFileConverter {
-
-        @Override
-        public Optional<JarFile> createJarFile(File file) {
-            try {
-                return of(new JarFile(file));
-            } catch (IOException e) {
-                return absent();
-            }
-        }
-    }
-
-    public static void unzip(File zipFile, File destFolder) throws IOException {
-        ZipInputStream zis = null;
-        try {
-            zis = new ZipInputStream(new FileInputStream(zipFile));
-            ZipEntry entry;
-            while ((entry = zis.getNextEntry()) != null) {
-                if (!entry.isDirectory()) {
-                    final File file = new File(destFolder, entry.getName());
-                    Files.createParentDirs(file);
-                    Files.asByteSink(file, FileWriteMode.APPEND).writeFrom(zis);
-                }
-            }
-        } finally {
-            Closeables.close(zis, true);
-        }
-    }
-
-    public static void zip(File directory, File out) throws IOException {
-        ZipOutputStream zos = null;
-        try {
-            OutputSupplier<FileOutputStream> s = Files.newOutputStreamSupplier(out);
-            zos = new ZipOutputStream(s.getOutput());
-            for (File f : FileUtils.listFiles(directory, FILE, DIRECTORY)) {
-                String path = removeStart(f.getPath(), directory.getAbsolutePath() + File.separator);
-                path = path.replace(File.separatorChar, '/');
-                ZipEntry e = new ZipEntry(path);
-                zos.putNextEntry(e);
-                Files.asByteSource(f).copyTo(zos);
-                zos.closeEntry();
-            }
-        } finally {
-            Closeables.close(zos, false);
-        }
-    }
-
-    /**
-     * Reads the give file into memory. This method may be used by zip based recommenders to speed up data access.
-     */
-    public static byte[] readFully(File file) throws IOException {
-        return toByteArray(newInputStreamSupplier(file));
-    }
-
-    /**
-     * Closes the give zip. Exceptions are printed to System.err.
-     */
-    public static boolean closeQuietly(@Nullable ZipFile z) {
-        if (z == null) {
-            return true;
-        }
-        try {
-            z.close();
-            return true;
-        } catch (IOException e) {
-            e.printStackTrace();
-            return false;
-        }
-    }
-}
diff --git a/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/utils/Zips.java b/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/utils/Zips.java
index 729a880..f4a888b 100644
--- a/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/utils/Zips.java
+++ b/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/utils/Zips.java
@@ -7,9 +7,6 @@
  */
 package org.eclipse.epp.internal.logging.aeri.ide.utils;
 
-import static com.google.common.base.Optional.*;
-import static com.google.common.io.ByteStreams.toByteArray;
-import static com.google.common.io.Files.newInputStreamSupplier;
 import static org.apache.commons.io.filefilter.DirectoryFileFilter.DIRECTORY;
 import static org.apache.commons.io.filefilter.FileFileFilter.FILE;
 import static org.apache.commons.lang3.StringUtils.removeStart;
@@ -18,18 +15,13 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.util.jar.JarFile;
+import java.text.MessageFormat;
 import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
 
 import org.apache.commons.io.FileUtils;
-import org.eclipse.jdt.annotation.Nullable;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.base.Throwables;
 import com.google.common.io.Closeables;
 import com.google.common.io.FileWriteMode;
 import com.google.common.io.Files;
@@ -37,51 +29,21 @@
 
 public class Zips {
 
-    public static ZipFile NULL() {
-        try {
-            File tmp = File.createTempFile("recommenders_null_zip", ".zip"); //$NON-NLS-1$ //$NON-NLS-2$
-            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(tmp));
-            zos.putNextEntry(new ZipEntry("/")); //$NON-NLS-1$
-            zos.closeEntry();
-            zos.close();
-            return new ZipFile(tmp);
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    /**
-     * This abstraction is used for testing.
-     */
-    @VisibleForTesting
-    public interface IFileToJarFileConverter {
-        Optional<JarFile> createJarFile(File file);
-    }
-
-    public static class DefaultJarFileConverter implements IFileToJarFileConverter {
-
-        @Override
-        public Optional<JarFile> createJarFile(File file) {
-            try {
-                return of(new JarFile(file));
-            } catch (IOException e) {
-                return absent();
-            }
-        }
-    }
-
     public static void unzip(File zipFile, File destFolder) throws IOException {
         ZipInputStream zis = null;
         try {
             zis = new ZipInputStream(new FileInputStream(zipFile));
-            ZipEntry entry;
-            while ((entry = zis.getNextEntry()) != null) {
+            ZipEntry entry = zis.getNextEntry();
+            if (entry == null) {
+                throw new IOException(MessageFormat.format("''{0}'' is empty or not a ZIP file.", zipFile));
+            }
+            do {
                 if (!entry.isDirectory()) {
                     final File file = new File(destFolder, entry.getName());
                     Files.createParentDirs(file);
                     Files.asByteSink(file, FileWriteMode.APPEND).writeFrom(zis);
                 }
-            }
+            } while ((entry = zis.getNextEntry()) != null);
         } finally {
             Closeables.close(zis, true);
         }
@@ -105,26 +67,4 @@
         }
     }
 
-    /**
-     * Reads the give file into memory. This method may be used by zip based recommenders to speed up data access.
-     */
-    public static byte[] readFully(File file) throws IOException {
-        return toByteArray(newInputStreamSupplier(file));
-    }
-
-    /**
-     * Closes the give zip. Exceptions are printed to System.err.
-     */
-    public static boolean closeQuietly(@Nullable ZipFile z) {
-        if (z == null) {
-            return true;
-        }
-        try {
-            z.close();
-            return true;
-        } catch (IOException e) {
-            e.printStackTrace();
-            return false;
-        }
-    }
 }
diff --git a/tests/org.eclipse.epp.logging.aeri.ide.tests/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/RemoteProblemsHistoryTest.java b/tests/org.eclipse.epp.logging.aeri.ide.tests/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/RemoteProblemsHistoryTest.java
index 9786259..1f2d870 100644
--- a/tests/org.eclipse.epp.logging.aeri.ide.tests/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/RemoteProblemsHistoryTest.java
+++ b/tests/org.eclipse.epp.logging.aeri.ide.tests/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/RemoteProblemsHistoryTest.java
@@ -7,7 +7,6 @@
 import static org.mockito.Mockito.*;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 
 import org.apache.http.HttpStatus;
@@ -28,6 +27,7 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.epp.internal.logging.aeri.ide.server.mars.ServerProblemsHistory.RemoteProblemsHistoryFilter;
 import org.eclipse.epp.internal.logging.aeri.ide.server.mars.ServerProblemsHistory.UpdateIndexJob;
+import org.eclipse.epp.internal.logging.aeri.ide.utils.Zips;
 import org.eclipse.epp.logging.aeri.core.ISystemSettings;
 import org.eclipse.epp.logging.aeri.core.ProblemStatus;
 import org.eclipse.epp.logging.aeri.core.ResetSendMode;
@@ -35,7 +35,9 @@
 import org.eclipse.epp.logging.aeri.tests.util.TestStatus;
 import org.eclipse.epp.logging.aeri.tests.util.TestStatuses;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
@@ -47,6 +49,9 @@
 
     private RAMDirectory directory;
 
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
     @Before
     public void setup() {
         sut = new ServerProblemsHistory(null) {
@@ -175,7 +180,7 @@
             @Override
             public Integer answer(InvocationOnMock invocation) throws Throwable {
                 File file = (File) invocation.getArguments()[0];
-                createEmptyZip(file);
+                createMinimalZipFile(file);
                 return HttpStatus.SC_OK;
             }
 
@@ -206,13 +211,10 @@
         }
     }
 
-    private static final byte[] MINIMAL_ZIP_FILE = { 80, 75, 05, 06, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
-            00 };
-
-    private static void createEmptyZip(File file) throws IOException {
-        FileOutputStream fos = new FileOutputStream(file);
-        fos.write(MINIMAL_ZIP_FILE, 0, 22);
-        fos.flush();
-        fos.close();
+    private void createMinimalZipFile(File file) throws IOException {
+        File folder = temporaryFolder.newFolder();
+        File f = new File(folder, "empty");
+        f.createNewFile();
+        Zips.zip(folder, file);
     }
 }