Skip to content

Commit cfe8e57

Browse files
Resources access reworked
1 parent e69d1a9 commit cfe8e57

26 files changed

Lines changed: 187 additions & 134 deletions

src/main/kotlin/com/haulmont/cuba/cli/CliContext.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class CliContext {
3333

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

36+
internal val plugins: List<CliPlugin> = mutableListOf()
37+
3638
/**
3739
* Retrieves model by [key].
3840
* The method produces exception, if the model doesn't exist,
@@ -53,6 +55,17 @@ class CliContext {
5355

5456
internal fun clearModels() = models.clear()
5557

58+
internal fun registerPlugin(plugin: CliPlugin) {
59+
(plugins as MutableList).add(plugin)
60+
}
61+
62+
fun getResources(pluginClass: Class<out CliPlugin>): Resources {
63+
return plugins.filterIsInstance(pluginClass)
64+
.firstOrNull()?.let {
65+
Resources(it)
66+
} ?: throw RuntimeException("Plugin $pluginClass was not loaded")
67+
}
68+
5669
/**
5770
* Returns all containing models.
5871
*/

src/main/kotlin/com/haulmont/cuba/cli/CliPlugin.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,11 @@ package com.haulmont.cuba.cli
6262
*
6363
* @see com.haulmont.cuba.cli.cubaplugin.CubaPlugin
6464
*/
65-
interface CliPlugin
65+
interface CliPlugin {
66+
val resources: ResourcesPath
67+
get() = NoResources
68+
}
69+
70+
sealed class ResourcesPath
71+
object NoResources: ResourcesPath()
72+
class HasResources(val resourcesBasePath: String) : ResourcesPath()

src/main/kotlin/com/haulmont/cuba/cli/EntryPoint.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ val kodein = Kodein {
7979

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

82-
bind<Resources>() with instance(Resources())
83-
8482
bind<WorkingDirectoryManager>() with instance(WorkingDirectoryManager())
8583

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

152151
bus.post(InitPluginEvent(commandsRegistry, mode))

src/main/kotlin/com/haulmont/cuba/cli/PlatformVersion.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.haulmont.cuba.cli
1818

19+
import org.kodein.di.direct
20+
import org.kodein.di.generic.instance
1921
import java.nio.file.Files
2022
import java.nio.file.Path
2123
import java.util.stream.Collectors
@@ -106,6 +108,16 @@ sealed class PlatformVersion : Comparable<PlatformVersion> {
106108
}
107109

108110
operator fun invoke(versionStr: String): PlatformVersion = parse(versionStr)
111+
112+
fun findVersion(): PlatformVersion {
113+
val context = kodein.direct.instance<CliContext>()
114+
if (context.hasModel(ProjectModel.MODEL_NAME)) {
115+
val model = context.getModel<ProjectModel>(ProjectModel.MODEL_NAME)
116+
return model.platformVersion
117+
}
118+
119+
return LatestVersion
120+
}
109121
}
110122
}
111123

src/main/kotlin/com/haulmont/cuba/cli/Resources.kt

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,77 @@
1616

1717
package com.haulmont.cuba.cli
1818

19+
import com.haulmont.cuba.cli.commands.CliCommand
20+
import org.kodein.di.direct
21+
import org.kodein.di.generic.instance
1922
import java.net.URI
2023
import java.nio.file.*
24+
import kotlin.properties.ReadOnlyProperty
25+
import kotlin.reflect.KProperty
2126

22-
class Resources {
27+
class Resources(private val cliPlugin: CliPlugin) {
2328

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

33-
val uri = clazz.getResource(resourceName)?.toURI()
3434

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

45-
private fun getFileSystem(templateUri: URI?) = try {
46-
FileSystems.getFileSystem(templateUri)
47-
} catch (e: FileSystemNotFoundException) {
48-
FileSystems.newFileSystem(templateUri, mutableMapOf<String, Any>())
40+
fun getSnippets(snippetsBasePath: String): Path {
41+
return getResourcePath(resourcesBasePath + "snippets/" + snippetsBasePath)
42+
?: throw RuntimeException("Snippets $snippetsBasePath not found in ${cliPlugin.javaClass} plugin")
43+
44+
}
45+
46+
fun getResourcePath(resourceName: String): Path? {
47+
return getResourcePath(resourceName, cliPlugin.javaClass)
4948
}
5049

5150
companion object {
51+
fun fromMyPlugin(): ReadOnlyProperty<CliCommand, Resources> = object : ReadOnlyProperty<CliCommand, Resources> {
52+
override fun getValue(thisRef: CliCommand, property: KProperty<*>): Resources {
53+
val context = kodein.direct.instance<CliContext>()
54+
55+
val plugin = context.plugins.find {
56+
it.javaClass.module == thisRef.javaClass.module
57+
}!!
58+
59+
return Resources(plugin)
60+
}
61+
}
62+
63+
fun getResourcePath(resourceName: String, clazz: Class<Any>): Path? {
64+
if (jrtFileSystem != null) {
65+
val moduleName = clazz.module.name
66+
val jrtPath = jrtFileSystem.getPath("/modules", moduleName, resourceName)
67+
if (Files.exists(jrtPath)) {
68+
return jrtPath
69+
}
70+
}
71+
72+
return clazz.getResource(resourceName)
73+
?.toURI()
74+
?.let {
75+
if (it.scheme == "jar") {
76+
val fileSystem = getFileSystem(it)
77+
fileSystem.getPath(resourceName)
78+
} else {
79+
Paths.get(it)
80+
}
81+
}
82+
}
83+
84+
private fun getFileSystem(templateUri: URI?) = try {
85+
FileSystems.getFileSystem(templateUri)
86+
} catch (e: FileSystemNotFoundException) {
87+
FileSystems.newFileSystem(templateUri, mutableMapOf<String, Any>())
88+
}
89+
5290
private val jrtFileSystem: FileSystem? = try {
5391
FileSystems.getFileSystem(URI.create("jrt:/"))
5492
} catch (e: Exception) {

src/main/kotlin/com/haulmont/cuba/cli/commands/GeneratorCommand.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,6 @@ abstract class GeneratorCommand<out Model : Any> : AbstractCommand() {
8585
abstract fun createModel(answers: Answers): Model
8686

8787
abstract fun generate(bindings: Map<String, Any>)
88-
89-
fun processTemplate(templateName: String, bindings: Map<String, Any>, block: TemplateProcessor.() -> Unit) {
90-
if (context.hasModel(ProjectModel.MODEL_NAME)) {
91-
TemplateProcessor(templateName, bindings, projectModel.platformVersion, block)
92-
} else {
93-
TemplateProcessor(templateName, bindings, LatestVersion, block)
94-
}
95-
}
9688
}
9789

9890
/**

src/main/kotlin/com/haulmont/cuba/cli/cubaplugin/CubaPlugin.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ import java.io.PrintWriter
4545

4646
@Suppress("UNUSED_PARAMETER")
4747
class CubaPlugin : CliPlugin {
48+
override val resources: ResourcesPath = HasResources("/com/haulmont/cuba/cli/cubaplugin/")
49+
4850
private val context: CliContext by kodein.instance()
4951

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

8486
@Subscribe
8587
fun beforeCommand(event: BeforeCommandExecutionEvent) {
86-
when(event.command) {
88+
when (event.command) {
8789
is CdCommand -> return
8890
}
8991

@@ -103,9 +105,4 @@ class CubaPlugin : CliPlugin {
103105
printHelper.saveStacktrace(e)
104106
}
105107
}
106-
107-
companion object {
108-
const val TEMPLATES_BASE_PATH = "/com/haulmont/cuba/cli/cubaplugin/templates/"
109-
const val SNIPPETS_BASE_PATH = "/com/haulmont/cuba/cli/cubaplugin/snippets/"
110-
}
111108
}

src/main/kotlin/com/haulmont/cuba/cli/cubaplugin/appcomponentxml/AppComponentCommand.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ import com.beust.jcommander.Parameters
2020
import com.haulmont.cuba.cli.ModuleStructure.Companion.CORE_MODULE
2121
import com.haulmont.cuba.cli.ModuleStructure.Companion.WEB_MODULE
2222
import com.haulmont.cuba.cli.PrintHelper
23+
import com.haulmont.cuba.cli.Resources
2324
import com.haulmont.cuba.cli.commands.GeneratorCommand
2425
import com.haulmont.cuba.cli.commands.NonInteractiveInfo
25-
import com.haulmont.cuba.cli.cubaplugin.CubaPlugin
2626
import com.haulmont.cuba.cli.generation.Properties
2727
import com.haulmont.cuba.cli.generation.Snippets
2828
import com.haulmont.cuba.cli.generation.TemplateProcessor
@@ -39,8 +39,10 @@ class AppComponentCommand : GeneratorCommand<AppComponentModel>(), NonInteractiv
3939

4040
private val printHelper: PrintHelper by kodein.instance()
4141

42+
private val resources by Resources.fromMyPlugin()
43+
4244
private val snippets: Snippets by lazy {
43-
Snippets(CubaPlugin.SNIPPETS_BASE_PATH + "appcomponentxml", javaClass, projectModel.platformVersion)
45+
Snippets(resources, "appcomponentxml", projectModel.platformVersion)
4446
}
4547

4648
override fun preExecute() {
@@ -95,7 +97,7 @@ class AppComponentCommand : GeneratorCommand<AppComponentModel>(), NonInteractiv
9597
changePrefix(model.modulePrefix)
9698
}
9799

98-
TemplateProcessor(CubaPlugin.TEMPLATES_BASE_PATH + "appComponent", bindings, projectModel.platformVersion) {
100+
TemplateProcessor(resources.getTemplate("appComponent"), bindings) {
99101
transformWhole()
100102
}
101103

src/main/kotlin/com/haulmont/cuba/cli/cubaplugin/browsescreen/CreateBrowseScreenCommand.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ package com.haulmont.cuba.cli.cubaplugin.browsescreen
1818

1919
import com.beust.jcommander.Parameters
2020
import com.haulmont.cuba.cli.ModuleStructure
21+
import com.haulmont.cuba.cli.Resources
2122
import com.haulmont.cuba.cli.commands.NonInteractiveInfo
22-
import com.haulmont.cuba.cli.cubaplugin.CubaPlugin
2323
import com.haulmont.cuba.cli.cubaplugin.ScreenCommandBase
2424
import com.haulmont.cuba.cli.generation.Properties
2525
import com.haulmont.cuba.cli.generation.TemplateProcessor
@@ -31,6 +31,8 @@ import net.sf.practicalxml.DomUtil
3131

3232
@Parameters(commandDescription = "Creates new browse screen")
3333
class CreateBrowseScreenCommand : ScreenCommandBase<BrowseScreenModel>(), NonInteractiveInfo {
34+
private val resources by Resources.fromMyPlugin()
35+
3436
override fun getModelName(): String = BrowseScreenModel.MODEL_NAME
3537

3638
override fun preExecute() {
@@ -116,7 +118,7 @@ class CreateBrowseScreenCommand : ScreenCommandBase<BrowseScreenModel>(), NonInt
116118
}
117119

118120
override fun generate(bindings: Map<String, Any>) {
119-
TemplateProcessor(CubaPlugin.TEMPLATES_BASE_PATH + "browseScreen", bindings, projectModel.platformVersion) {
121+
TemplateProcessor(resources.getTemplate("browseScreen"), bindings) {
120122
transformWhole()
121123
}
122124

src/main/kotlin/com/haulmont/cuba/cli/cubaplugin/componentbean/CreateComponentBeanCommand.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@
1717
package com.haulmont.cuba.cli.cubaplugin.componentbean
1818

1919
import com.beust.jcommander.Parameters
20+
import com.haulmont.cuba.cli.Resources
2021
import com.haulmont.cuba.cli.commands.GeneratorCommand
2122
import com.haulmont.cuba.cli.commands.NonInteractiveInfo
22-
import com.haulmont.cuba.cli.cubaplugin.CubaPlugin
2323
import com.haulmont.cuba.cli.generation.TemplateProcessor
2424
import com.haulmont.cuba.cli.prompting.Answers
2525
import com.haulmont.cuba.cli.prompting.QuestionsList
2626

2727
@Parameters(commandDescription = "Creates new Spring bean")
2828
class CreateComponentBeanCommand : GeneratorCommand<ComponentBeanModel>(), NonInteractiveInfo {
29+
private val resources by Resources.fromMyPlugin()
30+
2931
override fun getModelName(): String = ComponentBeanModel.MODEL_NAME
3032

3133
override fun preExecute() = checkProjectExistence()
@@ -67,7 +69,7 @@ class CreateComponentBeanCommand : GeneratorCommand<ComponentBeanModel>(), NonIn
6769
}
6870

6971
override fun generate(bindings: Map<String, Any>) {
70-
TemplateProcessor(CubaPlugin.TEMPLATES_BASE_PATH + "componentBean", bindings, projectModel.platformVersion) {
72+
TemplateProcessor(resources.getTemplate("componentBean"), bindings) {
7173
transformWhole()
7274
}
7375
}

0 commit comments

Comments
 (0)