From 78f5649001100cebd95482812f9d9decd3393a19 Mon Sep 17 00:00:00 2001 From: Jack Lynch Date: Fri, 25 Jul 2025 15:07:33 +0100 Subject: [PATCH] Make ZipFileReader AutoCloseable --- .../scala/io/apibuilder/validation/MultiService.scala | 11 +++++++++-- .../io/apibuilder/validation/zip/ZipFileReader.scala | 7 ++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/scala/io/apibuilder/validation/MultiService.scala b/src/main/scala/io/apibuilder/validation/MultiService.scala index 64c01be..2bdf355 100644 --- a/src/main/scala/io/apibuilder/validation/MultiService.scala +++ b/src/main/scala/io/apibuilder/validation/MultiService.scala @@ -7,6 +7,8 @@ import io.apibuilder.validation.util.{FileOrder, StandardErrors} import io.apibuilder.validation.zip.ZipFileReader import play.api.libs.json._ +import scala.util.Using + /** * Wrapper to work with multiple API Builder services. * Takes an ordered list of services. If multiple @@ -169,7 +171,8 @@ object MultiService { /** * Allow a client to read from for example s3 by providing a reader already constructed from the - * stream. + * stream. Note that the caller is responsible for ensuring that close() is called on the reader + * when done. */ def fromZipFileReader(reader: ZipFileReader): ValidatedNec[String, Seq[ApiBuilderService]] = { val fileSorter = FileOrder(reader.entries.find(_.name.toLowerCase() == OrderByFileName).map(_.file)) @@ -181,6 +184,10 @@ object MultiService { } private def servicesFromZip(url: String): ValidatedNec[String, Seq[ApiBuilderService]] = { - ZipFileReader.fromUrl(url).andThen(fromZipFileReader) + ZipFileReader + .fromUrl(url) + .andThen { zfr => + Using.resource(zfr)(fromZipFileReader) + } } } diff --git a/src/main/scala/io/apibuilder/validation/zip/ZipFileReader.scala b/src/main/scala/io/apibuilder/validation/zip/ZipFileReader.scala index d76f2a8..9386221 100644 --- a/src/main/scala/io/apibuilder/validation/zip/ZipFileReader.scala +++ b/src/main/scala/io/apibuilder/validation/zip/ZipFileReader.scala @@ -8,6 +8,7 @@ import java.nio.file.Files import java.util.zip.ZipEntry import java.util.zip.ZipInputStream import io.apibuilder.validation.util.UrlDownloader +import org.apache.commons.io.FileUtils object ZipFileReader { @@ -36,10 +37,14 @@ object ZipFileReader { } } -case class ZipFileReader(inputStream: InputStream) { +case class ZipFileReader(inputStream: InputStream) extends AutoCloseable { private val destDir: File = Files.createTempDirectory("zipfilereader").toFile + override def close(): Unit = { + FileUtils.deleteQuietly(destDir) + } + /** * Returns a list of the entries of the zip file (all files ending with .json) */