diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/InputStreamJarTemplate.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/InputStreamJarTemplate.kt new file mode 100644 index 00000000..aca69a0a --- /dev/null +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/InputStreamJarTemplate.kt @@ -0,0 +1,60 @@ +package com.beust.kobalt.api + +import com.beust.kobalt.Args +import com.beust.kobalt.misc.KFiles +import com.beust.kobalt.misc.kobaltLog +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.io.IOException +import java.net.URL +import java.util.jar.JarInputStream + +/** + * Base class for templates that simply decompress a jar file found on the classpath to generate their project. + */ +interface InputStreamJarTemplate : ITemplate { + val inputStream: JarInputStream + + override fun generateTemplate(args: Args, classLoader: ClassLoader) { + extractFile(inputStream, File(".")) + } + + private fun extractFile(ins: JarInputStream, destDir: File) { + var entry = ins.nextEntry + while (entry != null) { + val f = File(destDir.path + File.separator + entry.name) + if (entry.isDirectory) { + f.mkdir() + entry = ins.nextEntry + continue + } + + kobaltLog(2, " Extracting: $entry to ${f.absolutePath}") + FileOutputStream(f).use { fos -> + KFiles.copy(ins, fos) + } + entry = ins.nextEntry + } + } +} + +abstract class ResourceJarTemplate(val jarName: String, val classLoader: ClassLoader) : InputStreamJarTemplate { + override val inputStream = JarInputStream(classLoader.getResource(jarName).openConnection().inputStream) +} + +abstract class FileJarTemplate(val fileName: String, val classLoader: ClassLoader) : InputStreamJarTemplate { + override val inputStream = JarInputStream(FileInputStream(File(fileName))) +} + +abstract class HttpJarTemplate(val url: String, val classLoader: ClassLoader) : InputStreamJarTemplate { + override val inputStream : JarInputStream + get() { + try { + val result = URL(url).openConnection().inputStream + return JarInputStream(result) + } catch(ex: IOException) { + throw IllegalArgumentException("Couldn't connect to $url") + } + } +} diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/JarTemplate.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/JarTemplate.kt deleted file mode 100644 index 8c68b2b8..00000000 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/api/JarTemplate.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.beust.kobalt.api - -import com.beust.kobalt.Args -import com.beust.kobalt.misc.KFiles -import com.beust.kobalt.misc.kobaltLog -import java.io.File -import java.io.FileOutputStream -import java.util.jar.JarInputStream - -/** - * Base class for templates that simply decompress a jar file to generate their project. - */ -abstract class JarTemplate(val jarName: String) : ITemplate { - companion object { - fun extractFile(ins: JarInputStream, destDir: File) { - var entry = ins.nextEntry - while (entry != null) { - val f = File(destDir.path + File.separator + entry.name) - if (entry.isDirectory) { - f.mkdir() - entry = ins.nextEntry - continue - } - - kobaltLog(2, "Extracting: $entry to ${f.absolutePath}") - FileOutputStream(f).use { fos -> - KFiles.copy(ins, fos) - } - entry = ins.nextEntry - } - } - } - - override fun generateTemplate(args: Args, classLoader: ClassLoader) { - kobaltLog(2, "Generating template with class loader $classLoader") - val destDir = File(".") - val ins = JarInputStream(classLoader.getResource(jarName).openConnection().inputStream) - extractFile(ins, destDir) - } - -} diff --git a/src/main/kotlin/com/beust/kobalt/app/KobaltPluginTemplate.kt b/src/main/kotlin/com/beust/kobalt/app/KobaltPluginTemplate.kt index 2e4308c1..a498c7f4 100644 --- a/src/main/kotlin/com/beust/kobalt/app/KobaltPluginTemplate.kt +++ b/src/main/kotlin/com/beust/kobalt/app/KobaltPluginTemplate.kt @@ -1,7 +1,7 @@ package com.beust.kobalt.app import com.beust.kobalt.api.ITemplateContributor -import com.beust.kobalt.api.JarTemplate +import com.beust.kobalt.api.ResourceJarTemplate import com.beust.kobalt.plugin.KobaltPlugin /** @@ -12,7 +12,9 @@ class KobaltPluginTemplate : ITemplateContributor { val NAME = "kobaltPlugin" } - val pluginTemplate = object: JarTemplate(ITemplateContributor.DIRECTORY_NAME + "/$NAME/$NAME.jar") { + val pluginTemplate = object: ResourceJarTemplate( + ITemplateContributor.DIRECTORY_NAME + "/$NAME/$NAME.jar", + this::class.java.classLoader) { override val templateDescription = "Generate a sample Kobalt plug-in project" override val templateName = NAME diff --git a/src/main/kotlin/com/beust/kobalt/app/ProjectGenerator.kt b/src/main/kotlin/com/beust/kobalt/app/ProjectGenerator.kt index 5c436547..4f33ee32 100644 --- a/src/main/kotlin/com/beust/kobalt/app/ProjectGenerator.kt +++ b/src/main/kotlin/com/beust/kobalt/app/ProjectGenerator.kt @@ -1,6 +1,8 @@ package com.beust.kobalt.app import com.beust.kobalt.Args +import com.beust.kobalt.api.FileJarTemplate +import com.beust.kobalt.api.HttpJarTemplate import com.beust.kobalt.api.ITemplate import com.beust.kobalt.internal.PluginInfo import com.beust.kobalt.misc.kobaltLog @@ -22,14 +24,31 @@ class ProjectGenerator @Inject constructor(val pluginInfo: PluginInfo){ } args.templates?.split(',')?.forEach { templateName -> - val template = map[templateName] - if (template != null) { + + val finalTemplate: ITemplate? = map[templateName] + ?: if (File(templateName).exists()) { + kobaltLog(2, "Found a template jar file at $templateName, extracting it") + object : FileJarTemplate(templateName, classLoader) { + override val templateDescription = "Extract jar template from file" + override val templateName = "File template" + override val pluginName = "" + } + } else if (templateName.startsWith("http://") || templateName.startsWith("https://")) { + object : HttpJarTemplate(templateName, classLoader) { + override val templateDescription = "Extract jar template from HTTP" + override val templateName = "HTTP template" + override val pluginName = "" + } + } else { + warn("Couldn't find any template named $templateName") + null + } + + finalTemplate?.let { kobaltLog(2, "Running template $templateName") - template.generateTemplate(args, classLoader) + it.generateTemplate(args, classLoader) kobaltLog(1, "\n\nTemplate \"$templateName\" installed") - kobaltLog(1, template.instructions) - } else { - warn("Couldn't find any template named $templateName") + kobaltLog(1, finalTemplate.instructions) } } }