All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.name.remal.gradle_plugins.dsl.artifact.Artifact.kt Maven / Gradle / Ivy

The newest version!
package name.remal.gradle_plugins.dsl.artifact

import name.remal.gradle_plugins.dsl.utils.PathMatcher
import name.remal.gradle_plugins.dsl.utils.readJavaModuleName
import name.remal.nullIfEmpty
import name.remal.use
import java.io.BufferedInputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.InputStream
import java.util.zip.ZipException
import java.util.zip.ZipFile
import java.util.zip.ZipInputStream

class Artifact(file: File) : BaseHasEntries(), Comparable {

    val file: File = file.absoluteFile

    override val entryNames: Set by lazy {
        val result = sortedSetOf()
        if (file.isFile) {
            try {
                ZipFile(file).use { zipFile ->
                    val entries = zipFile.entries()
                    while (entries.hasMoreElements()) {
                        val entry = entries.nextElement()
                        if (entry.isDirectory) continue
                        result += entry.name
                    }
                }

            } catch (e: ZipException) {
                // do nothing
            }

        } else if (file.isDirectory) {
            file.walk().filter { file != it }.filter(File::isFile).forEach { resourceFile ->
                result += resourceFile.relativeTo(file).path.replace(File.separatorChar, '/')
            }
        }
        return@lazy result.toSet()
    }

    override fun openStream(entryName: String): InputStream {
        if (file.isFile) {
            val zipFile = ZipFile(file)
            val entry = zipFile.getEntry(entryName) ?: throw ArtifactEntryNotFoundException("Artifact entry not found: $entryName")
            val inputStream = zipFile.getInputStream(entry)!!
            return object : BufferedInputStream(inputStream) {
                override fun close() {
                    super.close()
                    zipFile.close()
                }
            }

        } else if (file.isDirectory) {
            try {
                return File(file, entryName).inputStream()
            } catch (e: FileNotFoundException) {
                throw ArtifactEntryNotFoundException("Artifact entry not found: $entryName", e)
            }

        } else {
            throw ArtifactFileNotFoundException("Artifact file not found: $file")
        }
    }

    @Suppress("ComplexMethod")
    override fun forEachEntry(pattern: String?, action: (entry: HasEntries.Entry) -> Unit) {
        val matcher = pattern.nullIfEmpty()?.let { PathMatcher(it) }
        if (file.isFile) {
            FileInputStream(file).use { fileInput ->
                ZipInputStream(fileInput).use { zipInput ->
                    while (true) {
                        val entry = zipInput.nextEntry ?: break
                        if (entry.isDirectory) continue
                        val entryName = entry.name
                        if (matcher == null || matcher.matches(entryName)) {
                            action(HasEntries.Entry(entryName, { zipInput }))
                        }
                    }
                }
            }

        } else if (file.isDirectory) {
            file.walk().filter { file != it }.forEach { entryFile ->
                val entryName = entryFile.relativeTo(file).invariantSeparatorsPath
                if (matcher == null || matcher.matches(entryName)) {
                    if (entryFile.isFile) {
                        var streamToClose: InputStream? = null
                        try {
                            action(HasEntries.Entry(entryName, { FileInputStream(entryFile).also { streamToClose = it } }))
                        } finally {
                            streamToClose?.close()
                        }
                    }
                }
            }
        }
    }

    val javaModuleName: String? by lazy { readJavaModuleName(file) }

    private val absolutePath: String = this.file.path
    override fun toString(): String = absolutePath
    override fun equals(other: Any?) = other is Artifact && absolutePath == other.absolutePath
    override fun hashCode() = absolutePath.hashCode()
    override fun compareTo(other: Artifact) = file.compareTo(other.file)

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy