Skip to content

Commit

Permalink
not working with jte yet, files need to be compiled
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Schuehly committed Aug 12, 2023
1 parent 0406d96 commit a8ae285
Show file tree
Hide file tree
Showing 29 changed files with 332 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package de.tschuehly.spring.viewcomponent.core
import de.tschuehly.spring.viewcomponent.core.processor.ViewComponentChangeListener
import de.tschuehly.spring.viewcomponent.core.processor.ViewComponentProcessingException
import jakarta.annotation.PostConstruct
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.boot.devtools.filewatch.FileSystemWatcher
Expand All @@ -15,25 +16,22 @@ import java.time.Duration

@Configuration
@ComponentScan("de.tschuehly.spring.viewcomponent.core")
class ViewComponentAutoConfiguration(
private val applicationContext: ApplicationContext
) {
class ViewComponentAutoConfiguration{

@Configuration
@ConditionalOnProperty("spring.view-component.local-development")
class LocalDevConfig {
val gradleKotlinBuildDir = "build/classes/kotlin/main/"

private val logger = LoggerFactory.getLogger(LocalDevConfig::class.java)
@Bean
fun viewComponentFileSystemWatcher(applicationContext: ApplicationContext): FileSystemWatcher {
val fileSystemWatcher = FileSystemWatcher(true, Duration.ofMillis(300), Duration.ofMillis(200))
val classPath =
applicationContext.getBeansWithAnnotation(SpringBootApplication::class.java).values.first().javaClass.protectionDomain.codeSource.location.path


val srcDir = getSrcDir(classPath)

logger.info("Registering fileSystemWatcher: ${srcDir.path}")
fileSystemWatcher.addSourceDirectory(srcDir)

fileSystemWatcher.addListener(ViewComponentChangeListener(applicationContext))
return fileSystemWatcher
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class ViewComponentChangeListener(
changeSet.any { changedFiles ->
changedFiles.files.any {
it.relativeName.endsWith(".html") ||
it.relativeName.endsWith(".jte")
it.relativeName.endsWith(".th") ||
it.relativeName.endsWith(".jte") ||
it.relativeName.endsWith(".kte")
}
}
) {
Expand Down Expand Up @@ -52,8 +54,7 @@ class ViewComponentChangeListener(
}
return@mapNotNull null
}
println(javaClass)
parser.parseFile(srcFile,methodList,javaClass.simpleName.lowercase())
parser.parseFile(srcFile, methodList, javaClass.simpleName.lowercase())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,18 @@ class ViewComponentParser() {
viewComponentName: String,
messager: Messager? = null
) {

// TODO: do it when DevTool ChangeListener detects changes
val resourceFileWriter = resourceHtmlFile.printWriter()
srcHtmlFile.forEachLine { htmlLine ->

if (htmlLine.contains("view:action")) {
val beforeViewAction = htmlLine.split("view:action=\"")[0]
val viewActionAttrVal = htmlLine.split("view:action=\"")[1].split("\"")[0]
val afterViewActionAttrVal = htmlLine.split("view:action=\"")[1].split("\"")[1]
val methodName = if (viewActionAttrVal.startsWith("|") &&
viewActionAttrVal.contains("?")
) {
viewActionAttrVal.substring(1, viewActionAttrVal.indexOf("?"))
val methodName = if (viewActionAttrVal.contains("?")) {
if(viewActionAttrVal.startsWith("|")){
viewActionAttrVal.substring(1, viewActionAttrVal.indexOf("?"))
}else{
viewActionAttrVal.substring(0, viewActionAttrVal.indexOf("?"))
}
} else {
viewActionAttrVal
}
Expand All @@ -81,14 +80,12 @@ class ViewComponentParser() {
val htmxAttrVal = viewActionAttrVal.replace(methodName, path, true)
val newLine =
"$beforeViewAction$htmxAttr\"$htmxAttrVal\" hx-target=\"#$viewComponentName\"$afterViewActionAttrVal"

resourceFileWriter.write(newLine)
resourceFileWriter.println()
messager?.let {
messager.printMessage(Diagnostic.Kind.NOTE, "old: $htmlLine")
messager.printMessage(Diagnostic.Kind.NOTE, "new: $newLine")
}

} else if (htmlLine.contains("<body")) {
val bodyEl = htmlLine.replace("<body", "<body id=\"$viewComponentName\"")
resourceFileWriter.write(bodyEl)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package de.tschuehly.spring.viewcomponent.core.processor

import de.tschuehly.spring.viewcomponent.core.action.*
import java.io.File
import java.nio.file.FileSystems
import java.nio.file.Path
import javax.annotation.processing.AbstractProcessor
import javax.annotation.processing.RoundEnvironment
import javax.annotation.processing.SupportedAnnotationTypes
Expand All @@ -14,8 +16,7 @@ import javax.tools.Diagnostic

@SupportedAnnotationTypes("de.tschuehly.spring.viewcomponent.core.component.ViewComponent")
@SupportedSourceVersion(SourceVersion.RELEASE_17)
class ViewComponentProcessor(
) : AbstractProcessor() {
class ViewComponentProcessor : AbstractProcessor() {
override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
val viewComponentParser = ViewComponentParser()
for (annotation in annotations) {
Expand All @@ -24,7 +25,6 @@ class ViewComponentProcessor(
proc.messager.printMessage(Diagnostic.Kind.NOTE, proc.options.toString())
proc.options["kapt.kotlin.generated"]?.let { filePath ->
// TODO: Only works with kapt currently. No java support yet
// TODO: Maybe integrate back into core?
val seperator = FileSystems.getDefault().separator
val rootDir = filePath.split("build")[0].split(seperator)
FileSystems.getDefault().getPath("", *rootDir.toTypedArray())
Expand All @@ -33,7 +33,7 @@ class ViewComponentProcessor(
val srcDirPath = FileSystems.getDefault()
.getPath("", *rootDir.toTypedArray(), "src", "main", "kotlin", directoryPath)
val methodList = getViewActionMethods(element)
val srcHtmlFile = srcDirPath.resolve("$elementPath.html").toFile()
val srcHtmlFile = getSrcHtmlFile(srcDirPath, elementPath)
val viewComponentName = element.simpleName.toString().lowercase()
viewComponentParser.parseFile(srcHtmlFile, methodList, viewComponentName, proc.messager)
}
Expand All @@ -42,6 +42,15 @@ class ViewComponentProcessor(
return true
}

private fun getSrcHtmlFile(srcDirPath: Path, elementPath: String): File {
val fileEndings = listOf(".html",".jte",".kte",".th")
fileEndings.forEach {
val file = srcDirPath.resolve("$elementPath$it").toFile()
if(file.exists()) return file
}
throw ViewComponentProcessingException("Couldn't find a file at ${srcDirPath.resolve(elementPath)}",null)
}

private fun getViewActionMethods(element: Element): List<ViewActionMethod> {
val methodList = element.enclosedElements.filter { it.kind == ElementKind.METHOD }.mapNotNull { method ->
if (method.getAnnotation(GetViewAction::class.java) != null) {
Expand Down
24 changes: 5 additions & 19 deletions examples/jte-demo/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("org.springframework.boot") version "3.0.6"
id("org.springframework.boot") version "3.1.2"
id("io.spring.dependency-management") version "1.1.2"
kotlin("jvm") version "1.7.22"
kotlin("plugin.spring") version "1.7.22"
kotlin("jvm") version "1.8.21"
kotlin("plugin.spring") version "1.8.21"
kotlin("kapt") version "1.8.21"
}

group = "de.tschuehly"
Expand All @@ -18,7 +19,7 @@ repositories {

dependencies {
implementation("de.tschuehly:spring-view-component-jte:0.6.1-SNAPSHOT")
// implementation("de.tschuehly:spring-view-component-jte")
kapt("de.tschuehly:spring-view-component-core:0.6.1-SNAPSHOT")

implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-web")
Expand All @@ -38,19 +39,4 @@ tasks.withType<KotlinCompile> {

tasks.withType<Test> {
useJUnitPlatform()
}

sourceSets {
main {
resources {
srcDir("src/main/kotlin")
exclude("**/*.kt")
}
}
test {
resources {
srcDir("src/test/kotlin")
exclude("**/*.kt")
}
}
}
22 changes: 11 additions & 11 deletions examples/jte-demo/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
rootProject.name = "jte-demo"
rootProject.name = "jte-kotlin-example"

//includeBuild("..\\..\\jte"){
// dependencySubstitution {
// substitute(module("de.tschuehly:spring-view-component-jte")).using(project(":"))
// }
//}
//includeBuild("..\\..\\core"){
// dependencySubstitution {
// substitute(module("de.tschuehly:spring-view-component-core")).using(project(":"))
// }
//}
includeBuild("..\\..\\jte"){
dependencySubstitution {
substitute(module("de.tschuehly:spring-view-component-jte")).using(project(":"))
}
}
includeBuild("..\\..\\core"){
dependencySubstitution {
substitute(module("de.tschuehly:spring-view-component-core")).using(project(":"))
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
package de.tschuehly.jteviewcomponentdemo.core

import org.springframework.stereotype.Service
import java.util.NoSuchElementException

@Service
class ExampleService {
fun getSomeData() = "Hey everyone JTE Templating works!"
var dataIndex = 0
val itemList = mutableMapOf<Int, String>()

fun getHelloWorld(): String {
return "Hello World"
}

fun addItemToList(item: String){
itemList[dataIndex] = item
dataIndex += 1
}

fun deleteItem(id: Int) {
itemList.remove(id) ?: throw NoSuchElementException("No Element with Id: $id found")
}


}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package de.tschuehly.jteviewcomponentdemo.web

import de.tschuehly.jteviewcomponentdemo.web.action.ActionViewComponent
import de.tschuehly.jteviewcomponentdemo.web.header.HeaderViewComponent
import de.tschuehly.jteviewcomponentdemo.web.index.IndexViewComponent
import de.tschuehly.jteviewcomponentdemo.web.layout.LayoutViewComponent
import de.tschuehly.jteviewcomponentdemo.web.simple.SimpleViewComponent
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.ModelAttribute

@Controller
class TestController(
private val simpleViewComponent: SimpleViewComponent,
private val indexViewComponent: IndexViewComponent,
private val layoutViewComponent: LayoutViewComponent,
private val headerViewComponent: HeaderViewComponent,
private val actionViewComponent: ActionViewComponent
) {

@GetMapping("/")
fun indexComponent() = indexViewComponent.render()

@GetMapping("/action")
fun actionComponent() = actionViewComponent.render()

@GetMapping("/nested-action")
fun nestedActionComponent() = layoutViewComponent.render(actionViewComponent.render())

@GetMapping("/simple")
fun simpleComponent() = simpleViewComponent.render()


@GetMapping("/layout")
fun layoutComponent() = layoutViewComponent.render(simpleViewComponent.render())

@GetMapping("/header")
fun header(): String {
return "test"
}

@ModelAttribute("header")
fun headerComponent() = headerViewComponent.render("TestTitle")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@param de.tschuehly.spring.viewcomponent.jte.application.web.action.ActionViewComponent.Person person
@param java.util.HashMap<Integer,String> itemList
@param Integer counter

<div>
<script defer src="/webjars/htmx.org/dist/htmx.min.js"></script>
<h2>ViewAction Get CountUp</h2>

<button view:action="countUp">Default ViewAction [GET]</button>
<h3>${counter}</h3>


<h2>ViewAction Post AddItem</h2>
<form view:action="addItem">
<input type="text" name="item">
<button type="submit">Save Item</button>
</form>
<table>
<tr>
<th>Item</th>
<th>Action</th>
</tr>
@for(var item: itemList.entrySet())
<tr>
<td>
<span>${item.getValue()}</span>
</td>
<td>
<button view:action="deleteItem?id=${item.getKey()}">Delete Item ${item.getKey()}</button>
</td>
</tr>
@endfor
</table>

<h2>ViewAction Put/Patch Person Form</h2>

<form style="display: inline-grid; gap: 0.5rem">
<label>
Name <input type="text" name="name" value="${person.getName()}">
</label>
<label>
Age: <input type="number" name="age" value="${person.getAge()}">
</label>
<label>
Location: <input type="text" name="location" value="${person.getLocation()}">
</label>
<button type="submit" view:action="savePersonPut">Save Changes using Put</button>
<button type="submit" view:action="savePersonPatch">Save Changes using Patch</button>
</form>
</div>
Loading

0 comments on commit a8ae285

Please sign in to comment.