diff --git a/tmc-langs-framework/src/main/java/fi/helsinki/cs/tmc/langs/io/zip/StudentFileAwareZipper.java b/tmc-langs-framework/src/main/java/fi/helsinki/cs/tmc/langs/io/zip/StudentFileAwareZipper.java index 916ae756b..94c685f40 100644 --- a/tmc-langs-framework/src/main/java/fi/helsinki/cs/tmc/langs/io/zip/StudentFileAwareZipper.java +++ b/tmc-langs-framework/src/main/java/fi/helsinki/cs/tmc/langs/io/zip/StudentFileAwareZipper.java @@ -5,6 +5,7 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -109,13 +110,8 @@ private void writeToZip(Path currentPath, ZipArchiveOutputStream zipStream, Path log.trace("Writing {} to zip", currentPath); - String name = projectPath.getParent().relativize(currentPath).toString(); - - if (Files.isDirectory(currentPath)) { - log.trace("{} is a directory", currentPath); - // Must be "/", can not be replaces with File.separator - name += "/"; - } + Path relativePath = projectPath.getParent().relativize(currentPath); + String name = relativePathToZipCompliantName(relativePath, Files.isDirectory(currentPath)); ZipArchiveEntry entry = new ZipArchiveEntry(name); zipStream.putArchiveEntry(entry); @@ -129,4 +125,31 @@ private void writeToZip(Path currentPath, ZipArchiveOutputStream zipStream, Path log.trace("Closing entry"); zipStream.closeArchiveEntry(); } + + private static String relativePathToZipCompliantName(Path path, boolean isDirectory) { + log.trace("Generating zip-compliant filename from Path \"{}\", isDirectory: {}", path, isDirectory); + // zip standard says "/" is to be used as the path separator. + final char separator = '/'; + + StringBuilder sb = new StringBuilder(); + for (Path part : path) { + sb.append(part); + sb.append(separator); + } + + if (sb.length() == 0) { + log.trace("Path didn't have any name elements"); + return path.toString(); + } + + if (!isDirectory) { + // ZipArchiveEntry assumes the entry represents a directory if and only + // if the name ends with a forward slash "/". Remove the last "/" because + // this wasn't a directory. + log.trace("Path wasn't a directory, removing trailing slash"); + sb.deleteCharAt(sb.length() - 1); + } + + return sb.toString(); + } }