package org.slc.sli.ingestion.landingzone.validation;

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.slc.sli.ingestion.validation.ErrorReport;
import org.slc.sli.ingestion.validation.spring.SimpleValidatorSpring;

/**
 * Zip file validator.
 *
 * @author okrook
 *
 */
public class ZipFileValidator extends SimpleValidatorSpring<File> {

    @Override
    public boolean isValid(File zipFile, ErrorReport callback) {

        ZipFile zf = null;

        try {
            zf = new ZipFile(zipFile);
        } catch (IOException ex) {
         // error reading zip file
            fail(callback, getFailureMessage("SL_ERR_MSG4", zipFile.getName()));
            return false;
        }

        Enumeration<?> entries = zf.entries();

        boolean isValid = false;
        while (entries.hasMoreElements()) {

            ZipEntry ze = (ZipEntry) entries.nextElement();

            if (isDirectory(ze)) {
                fail(callback, getFailureMessage("SL_ERR_MSG15", zipFile.getName()));
                return false;
            }

            if (ze.getName().endsWith(".ctl")) {
                isValid = true;
            }
        }

        // no manifest (.ctl file) found in the zip file
        if (!isValid) {
            fail(callback, getFailureMessage("SL_ERR_MSG5", zipFile.getName()));
        }
        return isValid;
    }

    private static boolean isDirectory(ZipEntry zipEntry) {

        if (zipEntry.isDirectory()) {
            return true;
        }


        //UN: This check is to ensure that any zipping utility which does not pack a directory entry
        //    is verified by checking for a filename with '/'. Example: Windows Zipping Tool.
        if (zipEntry.getName().contains("/")) {
            return true;
        }

        return false;
    }
}

@@ -63,20 +63,88 @@
 java.io.
-File
+BufferedInputStream;%0Aimport java.io.File;%0Aimport java.io.FileInputStream
 ;%0Aimport
@@ -169,97 +169,176 @@
 on;%0A
+%0A
 import 
-java.util.Enumeration;%0Aimport java.util.zip.ZipEntry;%0Aimport java.util.zip.ZipFile
+org.apache.commons.compress.archivers.ArchiveEntry;%0Aimport org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;%0Aimport org.apache.commons.io.IOUtils
 ;%0A%0Ai
@@ -676,18 +676,27 @@
     
-Zip
 File
- zf
+InputStream fis
  = n
@@ -700,25 +700,24 @@
 = null;%0A
-%0A
         
 try %7B%0A  
@@ -712,428 +712,306 @@
     
-try %7B%0A            zf = new ZipFile(zipFile);%0A        %7D catch (IOException ex) %7B%0A         // error reading zip file%0A            fail(callback, getFailureMessage(%22SL_ERR_MSG4%22, zipFile.getName()));%0A            return false;%0A        %7D%0A%0A        Enumeration%3C?%3E entries = zf.entries();%0A%0A        boolean isValid = false;%0A        while (entries.hasMoreElements()) %7B%0A%0A            ZipEntry ze = (ZipEntry) entries.nextElement();%0A%0A
+ZipArchiveInputStream zis = null;%0A%0A        boolean isValid = false;%0A%0A        try %7B%0A            fis = new FileInputStream(zipFile);%0A            zis = new ZipArchiveInputStream(new BufferedInputStream(fis));%0A%0A            ArchiveEntry ze;%0A%0A            while ((ze = zis.getNextEntry()) != null) %7B%0A%0A    
     
@@ -1037,24 +1037,28 @@
 tory(ze)) %7B%0A
+    
             
@@ -1139,32 +1139,36 @@
                 
+    
 return false;%0A  
@@ -1169,35 +1169,43 @@
 se;%0A            
+    
 %7D%0A%0A
+    
             if (
@@ -1253,16 +1253,20 @@
         
+    
 isValid 
@@ -1285,26 +1285,33 @@
         
-%7D%0A
+    %7D%0A   
         
 %7D%0A%0A     
@@ -1294,35 +1294,40 @@
    %7D%0A           
+ 
 %7D%0A%0A
+    
         // no ma
@@ -1371,24 +1371,28 @@
 ile%0A        
+    
 if (!isValid
@@ -1391,24 +1391,28 @@
 !isValid) %7B%0A
+    
             
@@ -1472,32 +1472,324 @@
 le.getName()));%0A
+            %7D%0A        %7D catch (IOException ex) %7B%0A            // error reading zip file%0A            fail(callback, getFailureMessage(%22SL_ERR_MSG4%22, zipFile.getName()));%0A            return false;%0A        %7D finally %7B%0A            IOUtils.closeQuietly(zis);%0A            IOUtils.closeQuietly(fis);%0A
         %7D%0A      
@@ -1852,19 +1852,23 @@
 rectory(
-Zip
+Archive
 Entry zi

Fix for DE999