From 283e0d578b37f131479c800ac7952c445979a3a4 Mon Sep 17 00:00:00 2001
From: Riegel <alexander.riegel@hft-stuttgart.de>
Date: Thu, 28 Nov 2024 10:18:52 +0100
Subject: [PATCH] Feat: Add exporting of CityGmlArchive to zip-file

---
 .../citydoctor2/ziploader/CityGmlArchive.java | 11 +--
 .../ziploader/utils/ArchivePacker.java        | 98 +++++++++++++++++++
 .../citydoctor2/ziploader/ZipTest.java        |  5 +
 3 files changed, 106 insertions(+), 8 deletions(-)
 create mode 100644 CityDoctorParent/Extensions/CityDoctorZipLoader/src/main/java/de/hft/stuttgart/citydoctor2/ziploader/utils/ArchivePacker.java

diff --git a/CityDoctorParent/Extensions/CityDoctorZipLoader/src/main/java/de/hft/stuttgart/citydoctor2/ziploader/CityGmlArchive.java b/CityDoctorParent/Extensions/CityDoctorZipLoader/src/main/java/de/hft/stuttgart/citydoctor2/ziploader/CityGmlArchive.java
index 67875ef..80ae8ae 100644
--- a/CityDoctorParent/Extensions/CityDoctorZipLoader/src/main/java/de/hft/stuttgart/citydoctor2/ziploader/CityGmlArchive.java
+++ b/CityDoctorParent/Extensions/CityDoctorZipLoader/src/main/java/de/hft/stuttgart/citydoctor2/ziploader/CityGmlArchive.java
@@ -1,7 +1,9 @@
 package de.hft.stuttgart.citydoctor2.ziploader;
 
 import de.hft.stuttgart.citydoctor2.check.Checker;
+import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
 import de.hft.stuttgart.citydoctor2.parser.ParserConfiguration;
+import de.hft.stuttgart.citydoctor2.ziploader.utils.ArchivePacker;
 import org.apache.commons.io.FileUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -68,14 +70,7 @@ public class CityGmlArchive {
     }
 
     public void exportToZipFile(String path)  {
-        if (!path.endsWith(".zip")){
-            throw new IllegalArgumentException("Target zip-filepath must end with '.zip'");
-        }
-
-
-        if (validated) {
-            //TODO: Export of validation reports for each entry
-        }
+        ArchivePacker.packArchive(path, this);
     }
 
     public void checkEntries(){
diff --git a/CityDoctorParent/Extensions/CityDoctorZipLoader/src/main/java/de/hft/stuttgart/citydoctor2/ziploader/utils/ArchivePacker.java b/CityDoctorParent/Extensions/CityDoctorZipLoader/src/main/java/de/hft/stuttgart/citydoctor2/ziploader/utils/ArchivePacker.java
new file mode 100644
index 0000000..7bbfab8
--- /dev/null
+++ b/CityDoctorParent/Extensions/CityDoctorZipLoader/src/main/java/de/hft/stuttgart/citydoctor2/ziploader/utils/ArchivePacker.java
@@ -0,0 +1,98 @@
+package de.hft.stuttgart.citydoctor2.ziploader.utils;
+
+import de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel;
+import de.hft.stuttgart.citydoctor2.ziploader.CityGmlArchive;
+import de.hft.stuttgart.citydoctor2.ziploader.CityGmlZipEntry;
+import org.apache.commons.io.FileUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public class ArchivePacker {
+
+    private static final Logger logger = LogManager.getLogger(ArchivePacker.class);
+
+    private ArchivePacker(){}
+
+    public static void packArchive(String targetPath, CityGmlArchive archive){
+        if (!targetPath.endsWith(".zip")){
+            throw new IllegalArgumentException("Target zip-filepath must end with '.zip'");
+        }
+        Path tmpDir = null;
+        try{
+            tmpDir = Files.createTempDirectory("zipTmp");
+            tmpDir.toFile().deleteOnExit();
+            for (CityGmlZipEntry entry : archive.getEntries()) {
+                if (entry.isErroneousEntry()){
+                    continue;
+                }
+                CityDoctorModel model = entry.getModel();
+                String filename = tmpDir.toString() + "\\" + entry.getFileName();
+                model.saveAs(filename, entry.isValidated());
+            }
+            zipDirectory(targetPath, tmpDir.toString());
+
+        }catch (Exception e){
+            logger.error(e);
+        } finally {
+            if (tmpDir != null) {
+                try {
+                    FileUtils.deleteDirectory(tmpDir.toFile());
+                } catch (IOException e) {
+                    logger.error(e);
+                }
+            }
+        }
+    }
+
+    private static void zipDirectory(String targetPath, String sourcePath){
+        List<String> fileList = new ArrayList<>();
+        File directory = new File(sourcePath);
+        for (String file : directory.list()){
+            fileList.add(file);
+        }
+
+        byte[] buffer = new byte[1024];
+        String source = new File(sourcePath).getName();
+        FileOutputStream fos = null;
+        ZipOutputStream zos = null;
+        try {
+            fos = new FileOutputStream(targetPath);
+            zos = new ZipOutputStream(fos);
+            FileInputStream in = null;
+            for (String file : fileList){
+                ZipEntry ze = new ZipEntry(file);
+                zos.putNextEntry(ze);
+                try {
+                    in = new FileInputStream(sourcePath +"\\" + file);
+                    int len;
+                    while ((len = in.read(buffer)) > 0) {
+                        zos.write(buffer, 0, len);
+                    }
+                }finally {
+                    if (in != null) {
+                        in.close();
+                    }
+                }
+            }
+            zos.closeEntry();
+            logger.info("Successfully created zip-archive");
+        } catch (IOException e) {
+            logger.error(e);
+        } finally {
+            try {
+                zos.close();
+            } catch (IOException e) {
+                logger.error(e);
+            }
+        }
+    }
+
+}
diff --git a/CityDoctorParent/Extensions/CityDoctorZipLoader/src/test/java/de/hft/stuttgart/citydoctor2/ziploader/ZipTest.java b/CityDoctorParent/Extensions/CityDoctorZipLoader/src/test/java/de/hft/stuttgart/citydoctor2/ziploader/ZipTest.java
index c024e11..2e97f7b 100644
--- a/CityDoctorParent/Extensions/CityDoctorZipLoader/src/test/java/de/hft/stuttgart/citydoctor2/ziploader/ZipTest.java
+++ b/CityDoctorParent/Extensions/CityDoctorZipLoader/src/test/java/de/hft/stuttgart/citydoctor2/ziploader/ZipTest.java
@@ -69,6 +69,11 @@ public class ZipTest {
             CityGmlArchive cgmlExport = CityGmlArchive.fromZipFile(expPath, config);
             assertNotNull(cgmlExport);
             assertEquals(5, cgmlExport.getEntries().size());
+            for (CityGmlZipEntry entry : cgmlExport.getEntries()) {
+                assertNotNull(entry);
+                assertTrue(entry.getFileName().matches("^mock[1-5].gml$"));
+                assertNotNull(entry.getModel());
+            }
         } catch (Exception e) {
             // Rethrow Exceptions to ensure deletion of tmpDir with finally block
             throw e;
-- 
GitLab