Skip to content

Commit

Permalink
Resources access reworked
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-shustanov committed Aug 31, 2018
1 parent e69d1a9 commit cfe8e57
Show file tree
Hide file tree
Showing 26 changed files with 187 additions and 134 deletions.
13 changes: 13 additions & 0 deletions src/main/kotlin/com/haulmont/cuba/cli/CliContext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class CliContext {

private val models: MutableMap<String, Any> = mutableMapOf()

internal val plugins: List<CliPlugin> = mutableListOf()

/**
* Retrieves model by [key].
* The method produces exception, if the model doesn't exist,
Expand All @@ -53,6 +55,17 @@ class CliContext {

internal fun clearModels() = models.clear()

internal fun registerPlugin(plugin: CliPlugin) {
(plugins as MutableList).add(plugin)
}

fun getResources(pluginClass: Class<out CliPlugin>): Resources {
return plugins.filterIsInstance(pluginClass)
.firstOrNull()?.let {
Resources(it)
} ?: throw RuntimeException("Plugin $pluginClass was not loaded")
}

/**
* Returns all containing models.
*/
Expand Down
9 changes: 8 additions & 1 deletion src/main/kotlin/com/haulmont/cuba/cli/CliPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,11 @@ package com.haulmont.cuba.cli
*
* @see com.haulmont.cuba.cli.cubaplugin.CubaPlugin
*/
interface CliPlugin
interface CliPlugin {
val resources: ResourcesPath
get() = NoResources
}

sealed class ResourcesPath
object NoResources: ResourcesPath()
class HasResources(val resourcesBasePath: String) : ResourcesPath()
3 changes: 1 addition & 2 deletions src/main/kotlin/com/haulmont/cuba/cli/EntryPoint.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ val kodein = Kodein {

bind<NamesUtils>() with instance(NamesUtils())

bind<Resources>() with instance(Resources())

bind<WorkingDirectoryManager>() with instance(WorkingDirectoryManager())

bind<PlatformVersionsManager>() with singleton { PlatformVersionsManager() }
Expand Down Expand Up @@ -147,6 +145,7 @@ private fun loadPlugins(commandsRegistry: CommandsRegistry, mode: CliMode) {
writer.println("Loaded plugin @|green ${plugin.javaClass.name}|@.")
}
bus.register(plugin)
context.registerPlugin(plugin)
}

bus.post(InitPluginEvent(commandsRegistry, mode))
Expand Down
12 changes: 12 additions & 0 deletions src/main/kotlin/com/haulmont/cuba/cli/PlatformVersion.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.haulmont.cuba.cli

import org.kodein.di.direct
import org.kodein.di.generic.instance
import java.nio.file.Files
import java.nio.file.Path
import java.util.stream.Collectors
Expand Down Expand Up @@ -106,6 +108,16 @@ sealed class PlatformVersion : Comparable<PlatformVersion> {
}

operator fun invoke(versionStr: String): PlatformVersion = parse(versionStr)

fun findVersion(): PlatformVersion {
val context = kodein.direct.instance<CliContext>()
if (context.hasModel(ProjectModel.MODEL_NAME)) {
val model = context.getModel<ProjectModel>(ProjectModel.MODEL_NAME)
return model.platformVersion
}

return LatestVersion
}
}
}

Expand Down
82 changes: 60 additions & 22 deletions src/main/kotlin/com/haulmont/cuba/cli/Resources.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,77 @@

package com.haulmont.cuba.cli

import com.haulmont.cuba.cli.commands.CliCommand
import org.kodein.di.direct
import org.kodein.di.generic.instance
import java.net.URI
import java.nio.file.*
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

class Resources {
class Resources(private val cliPlugin: CliPlugin) {

fun getResourcePath(resourceName: String, clazz: Class<Any>): Path? {
if (jrtFileSystem != null) {
val moduleName = clazz.module.name
val jrtPath = jrtFileSystem.getPath("/modules", moduleName, resourceName)
if (Files.exists(jrtPath)) {
return jrtPath
}
}
private val resourcesBasePath: String = cliPlugin.resources.let {
(it as? HasResources)?.resourcesBasePath
?: throw RuntimeException("Plugin ${cliPlugin.javaClass} doesn't support resources")
}

val uri = clazz.getResource(resourceName)?.toURI()

return if (uri != null) {
if (uri.scheme == "jar") {
val fileSystem = getFileSystem(uri)
fileSystem.getPath(resourceName)
} else {
Paths.get(uri)
}
} else null
fun getTemplate(templateName: String): Path {
return getResourcePath(resourcesBasePath + "templates/" + templateName)
?: throw RuntimeException("Template $templateName not found in ${cliPlugin.javaClass} plugin")
}

private fun getFileSystem(templateUri: URI?) = try {
FileSystems.getFileSystem(templateUri)
} catch (e: FileSystemNotFoundException) {
FileSystems.newFileSystem(templateUri, mutableMapOf<String, Any>())
fun getSnippets(snippetsBasePath: String): Path {
return getResourcePath(resourcesBasePath + "snippets/" + snippetsBasePath)
?: throw RuntimeException("Snippets $snippetsBasePath not found in ${cliPlugin.javaClass} plugin")

}

fun getResourcePath(resourceName: String): Path? {
return getResourcePath(resourceName, cliPlugin.javaClass)
}

companion object {
fun fromMyPlugin(): ReadOnlyProperty<CliCommand, Resources> = object : ReadOnlyProperty<CliCommand, Resources> {
override fun getValue(thisRef: CliCommand, property: KProperty<*>): Resources {
val context = kodein.direct.instance<CliContext>()

val plugin = context.plugins.find {
it.javaClass.module == thisRef.javaClass.module
}!!

return Resources(plugin)
}
}

fun getResourcePath(resourceName: String, clazz: Class<Any>): Path? {
if (jrtFileSystem != null) {
val moduleName = clazz.module.name
val jrtPath = jrtFileSystem.getPath("/modules", moduleName, resourceName)
if (Files.exists(jrtPath)) {
return jrtPath
}
}

return clazz.getResource(resourceName)
?.toURI()
?.let {
if (it.scheme == "jar") {
val fileSystem = getFileSystem(it)
fileSystem.getPath(resourceName)
} else {
Paths.get(it)
}
}
}

private fun getFileSystem(templateUri: URI?) = try {
FileSystems.getFileSystem(templateUri)
} catch (e: FileSystemNotFoundException) {
FileSystems.newFileSystem(templateUri, mutableMapOf<String, Any>())
}

private val jrtFileSystem: FileSystem? = try {
FileSystems.getFileSystem(URI.create("jrt:/"))
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,6 @@ abstract class GeneratorCommand<out Model : Any> : AbstractCommand() {
abstract fun createModel(answers: Answers): Model

abstract fun generate(bindings: Map<String, Any>)

fun processTemplate(templateName: String, bindings: Map<String, Any>, block: TemplateProcessor.() -> Unit) {
if (context.hasModel(ProjectModel.MODEL_NAME)) {
TemplateProcessor(templateName, bindings, projectModel.platformVersion, block)
} else {
TemplateProcessor(templateName, bindings, LatestVersion, block)
}
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import java.io.PrintWriter

@Suppress("UNUSED_PARAMETER")
class CubaPlugin : CliPlugin {
override val resources: ResourcesPath = HasResources("/com/haulmont/cuba/cli/cubaplugin/")

private val context: CliContext by kodein.instance()

private val writer: PrintWriter by kodein.instance()
Expand Down Expand Up @@ -83,7 +85,7 @@ class CubaPlugin : CliPlugin {

@Subscribe
fun beforeCommand(event: BeforeCommandExecutionEvent) {
when(event.command) {
when (event.command) {
is CdCommand -> return
}

Expand All @@ -103,9 +105,4 @@ class CubaPlugin : CliPlugin {
printHelper.saveStacktrace(e)
}
}

companion object {
const val TEMPLATES_BASE_PATH = "/com/haulmont/cuba/cli/cubaplugin/templates/"
const val SNIPPETS_BASE_PATH = "/com/haulmont/cuba/cli/cubaplugin/snippets/"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import com.beust.jcommander.Parameters
import com.haulmont.cuba.cli.ModuleStructure.Companion.CORE_MODULE
import com.haulmont.cuba.cli.ModuleStructure.Companion.WEB_MODULE
import com.haulmont.cuba.cli.PrintHelper
import com.haulmont.cuba.cli.Resources
import com.haulmont.cuba.cli.commands.GeneratorCommand
import com.haulmont.cuba.cli.commands.NonInteractiveInfo
import com.haulmont.cuba.cli.cubaplugin.CubaPlugin
import com.haulmont.cuba.cli.generation.Properties
import com.haulmont.cuba.cli.generation.Snippets
import com.haulmont.cuba.cli.generation.TemplateProcessor
Expand All @@ -39,8 +39,10 @@ class AppComponentCommand : GeneratorCommand<AppComponentModel>(), NonInteractiv

private val printHelper: PrintHelper by kodein.instance()

private val resources by Resources.fromMyPlugin()

private val snippets: Snippets by lazy {
Snippets(CubaPlugin.SNIPPETS_BASE_PATH + "appcomponentxml", javaClass, projectModel.platformVersion)
Snippets(resources, "appcomponentxml", projectModel.platformVersion)
}

override fun preExecute() {
Expand Down Expand Up @@ -95,7 +97,7 @@ class AppComponentCommand : GeneratorCommand<AppComponentModel>(), NonInteractiv
changePrefix(model.modulePrefix)
}

TemplateProcessor(CubaPlugin.TEMPLATES_BASE_PATH + "appComponent", bindings, projectModel.platformVersion) {
TemplateProcessor(resources.getTemplate("appComponent"), bindings) {
transformWhole()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ package com.haulmont.cuba.cli.cubaplugin.browsescreen

import com.beust.jcommander.Parameters
import com.haulmont.cuba.cli.ModuleStructure
import com.haulmont.cuba.cli.Resources
import com.haulmont.cuba.cli.commands.NonInteractiveInfo
import com.haulmont.cuba.cli.cubaplugin.CubaPlugin
import com.haulmont.cuba.cli.cubaplugin.ScreenCommandBase
import com.haulmont.cuba.cli.generation.Properties
import com.haulmont.cuba.cli.generation.TemplateProcessor
Expand All @@ -31,6 +31,8 @@ import net.sf.practicalxml.DomUtil

@Parameters(commandDescription = "Creates new browse screen")
class CreateBrowseScreenCommand : ScreenCommandBase<BrowseScreenModel>(), NonInteractiveInfo {
private val resources by Resources.fromMyPlugin()

override fun getModelName(): String = BrowseScreenModel.MODEL_NAME

override fun preExecute() {
Expand Down Expand Up @@ -116,7 +118,7 @@ class CreateBrowseScreenCommand : ScreenCommandBase<BrowseScreenModel>(), NonInt
}

override fun generate(bindings: Map<String, Any>) {
TemplateProcessor(CubaPlugin.TEMPLATES_BASE_PATH + "browseScreen", bindings, projectModel.platformVersion) {
TemplateProcessor(resources.getTemplate("browseScreen"), bindings) {
transformWhole()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@
package com.haulmont.cuba.cli.cubaplugin.componentbean

import com.beust.jcommander.Parameters
import com.haulmont.cuba.cli.Resources
import com.haulmont.cuba.cli.commands.GeneratorCommand
import com.haulmont.cuba.cli.commands.NonInteractiveInfo
import com.haulmont.cuba.cli.cubaplugin.CubaPlugin
import com.haulmont.cuba.cli.generation.TemplateProcessor
import com.haulmont.cuba.cli.prompting.Answers
import com.haulmont.cuba.cli.prompting.QuestionsList

@Parameters(commandDescription = "Creates new Spring bean")
class CreateComponentBeanCommand : GeneratorCommand<ComponentBeanModel>(), NonInteractiveInfo {
private val resources by Resources.fromMyPlugin()

override fun getModelName(): String = ComponentBeanModel.MODEL_NAME

override fun preExecute() = checkProjectExistence()
Expand Down Expand Up @@ -67,7 +69,7 @@ class CreateComponentBeanCommand : GeneratorCommand<ComponentBeanModel>(), NonIn
}

override fun generate(bindings: Map<String, Any>) {
TemplateProcessor(CubaPlugin.TEMPLATES_BASE_PATH + "componentBean", bindings, projectModel.platformVersion) {
TemplateProcessor(resources.getTemplate("componentBean"), bindings) {
transformWhole()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@ import com.beust.jcommander.Parameters
import com.haulmont.cuba.cli.ModuleStructure.Companion.CORE_MODULE
import com.haulmont.cuba.cli.ModuleStructure.Companion.GLOBAL_MODULE
import com.haulmont.cuba.cli.ModuleStructure.Companion.WEB_MODULE
import com.haulmont.cuba.cli.Resources
import com.haulmont.cuba.cli.commands.GeneratorCommand
import com.haulmont.cuba.cli.cubaplugin.CubaPlugin
import com.haulmont.cuba.cli.generation.TemplateProcessor
import com.haulmont.cuba.cli.prompting.Answers
import com.haulmont.cuba.cli.prompting.QuestionsList

@Parameters(commandDescription = "Creates new configuration interface")
class ConfigCommand : GeneratorCommand<ConfigModel>() {

private val resources by Resources.fromMyPlugin()

override fun getModelName(): String = ConfigModel.NAME

override fun preExecute() {
Expand Down Expand Up @@ -58,7 +60,7 @@ class ConfigCommand : GeneratorCommand<ConfigModel>() {
override fun createModel(answers: Answers): ConfigModel = ConfigModel(answers)

override fun generate(bindings: Map<String, Any>) {
TemplateProcessor(CubaPlugin.TEMPLATES_BASE_PATH + "config", bindings, projectModel.platformVersion) {
TemplateProcessor(resources.getTemplate("config"), bindings) {
transformWhole()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ package com.haulmont.cuba.cli.cubaplugin.editscreen

import com.beust.jcommander.Parameters
import com.haulmont.cuba.cli.ModuleStructure
import com.haulmont.cuba.cli.Resources
import com.haulmont.cuba.cli.commands.NonInteractiveInfo
import com.haulmont.cuba.cli.cubaplugin.CubaPlugin
import com.haulmont.cuba.cli.cubaplugin.ScreenCommandBase
import com.haulmont.cuba.cli.generation.Properties
import com.haulmont.cuba.cli.generation.TemplateProcessor
Expand All @@ -31,6 +31,9 @@ import net.sf.practicalxml.DomUtil

@Parameters(commandDescription = "Creates new edit screen")
class CreateEditScreenCommand : ScreenCommandBase<EditScreenModel>(), NonInteractiveInfo {

private val resources by Resources.fromMyPlugin()

override fun getModelName(): String = EditScreenModel.MODEL_NAME

override fun preExecute() {
Expand Down Expand Up @@ -116,7 +119,7 @@ class CreateEditScreenCommand : ScreenCommandBase<EditScreenModel>(), NonInterac
}

override fun generate(bindings: Map<String, Any>) {
TemplateProcessor(CubaPlugin.TEMPLATES_BASE_PATH + "editScreen", bindings, projectModel.platformVersion) {
TemplateProcessor(resources.getTemplate("editScreen"), bindings) {
transformWhole()
}

Expand Down
Loading

0 comments on commit cfe8e57

Please sign in to comment.