Browse Source

Merge pull request #608 from nestabentum/zip

Zip ReportViewer Files
Timur Sağlam 4 years ago
parent
commit
5bbee67afe

+ 0 - 32
jplag/src/main/java/de/jplag/reporting/jsonfactory/DirectoryCreator.java

@@ -1,32 +0,0 @@
-package de.jplag.reporting.jsonfactory;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Provides Methods for creating directories.
- */
-public class DirectoryCreator {
-
-    /**
-     * Creates a directory.
-     * @param path The path under which the new directory ought to be created
-     * @param name The name of the new directory
-     * @return The created directory
-     */
-    public static File createDirectory(String path, String name) throws IOException {
-        File directory = new File(path.concat("/").concat(name));
-        if (!directory.exists() && !directory.mkdirs()) {
-            throw new IOException("Failed to create dir.");
-        }
-        return directory;
-    }
-
-    /**
-     * Create a directory with the given path
-     * @param path The path of the new directory
-     */
-    public static void createDirectory(String path) throws IOException {
-        createDirectory(path, "");
-    }
-}

+ 93 - 0
jplag/src/main/java/de/jplag/reporting/jsonfactory/DirectoryManager.java

@@ -0,0 +1,93 @@
+package de.jplag.reporting.jsonfactory;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Comparator;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides Methods for creating directories.
+ */
+public class DirectoryManager {
+    private static final Logger logger = LoggerFactory.getLogger(DirectoryManager.class);
+
+    /**
+     * Creates a directory.
+     * @param path The path under which the new directory ought to be created
+     * @param name The name of the new directory
+     * @return The created directory
+     */
+    public static File createDirectory(String path, String name) throws IOException {
+        File directory = new File(path.concat("/").concat(name));
+        if (!directory.exists() && !directory.mkdirs()) {
+            throw new IOException("Failed to create dir.");
+        }
+        return directory;
+    }
+
+    /**
+     * Create a directory with the given path
+     * @param path The path of the new directory
+     */
+    public static void createDirectory(String path) throws IOException {
+        createDirectory(path, "");
+    }
+
+    /**
+     * Delete the directory and all of its contents, identified by the given path
+     * @param path The path that identifies the directory to delete
+     */
+    public static void deleteDirectory(String path) {
+        try (var f = Files.walk(Path.of(path))) {
+            f.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
+        } catch (IOException e) {
+            logger.error("Could not delete folder " + path, e);
+        }
+    }
+
+    /**
+     * Zip the directory identified by the given path
+     * @param path The path that identifies the directory to zip
+     * @return True if zip was successful, false otherwise
+     */
+    public static boolean zipDirectory(String path) {
+        Path p = Path.of(path);
+        String zipName = path + ".zip";
+
+        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipName))) {
+
+            Files.walkFileTree(p, new SimpleFileVisitor<>() {
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                    Path targetFile = p.relativize(file);
+                    zos.putNextEntry(new ZipEntry(targetFile.toString()));
+
+                    byte[] bytes = Files.readAllBytes(file);
+                    zos.write(bytes, 0, bytes.length);
+                    return FileVisitResult.CONTINUE;
+                }
+
+                @Override
+                public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
+                    logger.error("Unable to zip " + file, exc);
+                    throw exc;
+                }
+            });
+        } catch (IOException e) {
+            logger.error(e.getMessage(), e);
+            deleteDirectory(zipName);
+            return false;
+        }
+        return true;
+    }
+}

+ 20 - 9
jplag/src/main/java/de/jplag/reporting/reportobject/ReportObjectFactory.java

@@ -1,6 +1,6 @@
 package de.jplag.reporting.reportobject;
 
-import static de.jplag.reporting.jsonfactory.DirectoryCreator.createDirectory;
+import static de.jplag.reporting.jsonfactory.DirectoryManager.*;
 import static de.jplag.reporting.reportobject.mapper.SubmissionNameToIdMapper.buildSubmissionNameToIdMap;
 
 import java.io.File;
@@ -41,26 +41,37 @@ public class ReportObjectFactory {
     private Map<String, Map<String, String>> submissionNameToNameToComparisonFileName;
 
     /**
-     * Creates all necessary report viewer files and writes them to the disk.
+     * Creates all necessary report viewer files, writes them to the disk as zip.
      * @param result The JPlagResult to be converted into a report.
      * @param path The Path to save the report to
      */
     public void createAndSaveReport(JPlagResult result, String path) {
 
-        buildSubmissionToIdMap(result);
         try {
             createDirectory(path);
+            buildSubmissionToIdMap(result);
+
             copySubmissionFilesToReport(path, result);
 
             writeComparisons(result, path);
             writeOverview(result, path);
 
+            zipAndDelete(path);
         } catch (IOException e) {
             logger.error("Could not create directory " + path + " for report viewer generation", e);
         }
 
     }
 
+    private void zipAndDelete(String path) {
+        boolean zipWasSuccessful = zipDirectory(path);
+        if (zipWasSuccessful) {
+            deleteDirectory(path);
+        } else {
+            logger.error("Could not zip results. The results are still available uncompressed at " + path);
+        }
+    }
+
     private void buildSubmissionToIdMap(JPlagResult result) {
         submissionNameToIdMap = buildSubmissionNameToIdMap(result);
         submissionToIdFunction = (Submission submission) -> submissionNameToIdMap.get(submission.getName());
@@ -68,19 +79,19 @@ public class ReportObjectFactory {
 
     private void copySubmissionFilesToReport(String path, JPlagResult result) {
         List<JPlagComparison> comparisons = result.getComparisons(result.getOptions().getMaximumNumberOfComparisons());
-        var submissions = getSubmissions(comparisons);
-        var submissionsPath = createSubmissionsDirectory(path);
+        Set<Submission> submissions = getSubmissions(comparisons);
+        File submissionsPath = createSubmissionsDirectory(path);
         if (submissionsPath == null) {
             return;
         }
         Language language = result.getOptions().getLanguage();
-        for (var submission : submissions) {
+        for (Submission submission : submissions) {
             File directory = createSubmissionDirectory(path, submissionsPath, submission);
             if (directory == null) {
                 continue;
             }
-            for (var file : submission.getFiles()) {
-                var fileToCopy = language.useViewFiles() ? new File(file.getPath() + language.viewFileSuffix()) : file;
+            for (File file : submission.getFiles()) {
+                File fileToCopy = language.useViewFiles() ? new File(file.getPath() + language.viewFileSuffix()) : file;
                 try {
                     Files.copy(fileToCopy.toPath(), (new File(directory, file.getName())).toPath(), StandardCopyOption.REPLACE_EXISTING);
                 } catch (IOException e) {
@@ -141,7 +152,7 @@ public class ReportObjectFactory {
     }
 
     private Set<Submission> getSubmissions(List<JPlagComparison> comparisons) {
-        var submissions = comparisons.stream().map(JPlagComparison::getFirstSubmission).collect(Collectors.toSet());
+        Set<Submission> submissions = comparisons.stream().map(JPlagComparison::getFirstSubmission).collect(Collectors.toSet());
         Set<Submission> secondSubmissions = comparisons.stream().map(JPlagComparison::getSecondSubmission).collect(Collectors.toSet());
         submissions.addAll(secondSubmissions);
         return submissions;