diff --git a/examples/maven-spring-integration/pom.xml b/examples/maven-spring-integration/pom.xml index b4b068f84..6e0d3137d 100644 --- a/examples/maven-spring-integration/pom.xml +++ b/examples/maven-spring-integration/pom.xml @@ -25,7 +25,6 @@ spring-boot-starter-test test - community.flock.wirespec.integration spring-jvm @@ -43,6 +42,13 @@ community.flock.wirespec.plugin.maven wirespec-maven-plugin 0.0.0-SNAPSHOT + + + community.flock.wirespec.integration + spring-jvm + 0.0.0-SNAPSHOT + + java @@ -58,20 +64,14 @@ - - - community.flock.wirespec.integration - spring-jvm - 0.0.0-SNAPSHOT - - + org.apache.maven.plugins maven-compiler-plugin 3.8.0 - 17 + 21 --enable-preview diff --git a/examples/maven-spring-integration/src/main/java/community/flock/wirespec/examples/spring_boot_integration/TodoApplication.java b/examples/maven-spring-integration/src/main/java/community/flock/wirespec/examples/spring_boot_integration/TodoApplication.java index 603bfe70c..abc1e5b00 100644 --- a/examples/maven-spring-integration/src/main/java/community/flock/wirespec/examples/spring_boot_integration/TodoApplication.java +++ b/examples/maven-spring-integration/src/main/java/community/flock/wirespec/examples/spring_boot_integration/TodoApplication.java @@ -1,6 +1,6 @@ package community.flock.wirespec.examples.spring_boot_integration; -import community.flock.wirespec.integration.spring.configuration.WirespecConfiguration; +import community.flock.wirespec.integration.spring.java.configuration.WirespecConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/examples/maven-spring-integration/src/main/java/community/flock/wirespec/examples/spring_boot_integration/TodoController.java b/examples/maven-spring-integration/src/main/java/community/flock/wirespec/examples/spring_boot_integration/TodoController.java index d352c64a6..2051f7d87 100644 --- a/examples/maven-spring-integration/src/main/java/community/flock/wirespec/examples/spring_boot_integration/TodoController.java +++ b/examples/maven-spring-integration/src/main/java/community/flock/wirespec/examples/spring_boot_integration/TodoController.java @@ -7,7 +7,7 @@ import java.util.concurrent.CompletableFuture; @RestController -class TodoController implements GetTodosEndpoint, GetTodoByIdEndpoint, CreateTodoEndpoint, UpdateTodoEndpoint, DeleteTodoEndpoint { +class TodoController implements GetTodosEndpoint.Handler, GetTodoByIdEndpoint.Handler, CreateTodoEndpoint.Handler, UpdateTodoEndpoint.Handler, DeleteTodoEndpoint.Handler { private final TodoService service; @@ -16,9 +16,9 @@ public TodoController(TodoService service) { } @Override - public CompletableFuture> createTodo(CreateTodoEndpoint.Request request) { + public CompletableFuture> createTodo(CreateTodoEndpoint.Request request) { var todoInput = switch (request){ - case CreateTodoEndpoint.RequestApplicationJson req -> req.getContent().body(); + case CreateTodoEndpoint.Request req -> req.getBody(); }; var todo = new Todo( UUID.randomUUID().toString(), @@ -26,33 +26,33 @@ public CompletableFuture> createTodo(CreateTodoEn todoInput.done() ); service.create(todo); - var res = new CreateTodoEndpoint.Response200ApplicationJson(todo); + var res = new CreateTodoEndpoint.Response200(todo); return CompletableFuture.completedFuture(res); } @Override - public CompletableFuture> deleteTodo(DeleteTodoEndpoint.Request request) { + public CompletableFuture> deleteTodo(DeleteTodoEndpoint.Request request) { return null; } @Override - public CompletableFuture> getTodoById(GetTodoByIdEndpoint.Request request) { + public CompletableFuture> getTodoById(GetTodoByIdEndpoint.Request request) { var id = switch (request){ - case GetTodoByIdEndpoint.RequestUnit req -> req.getPath(); + case GetTodoByIdEndpoint.Request req -> req.getPath(); }; System.out.println(id); - var res = new GetTodoByIdEndpoint.Response200ApplicationJson(service.store.get(0)); + var res = new GetTodoByIdEndpoint.Response200(service.store.get(0)); return CompletableFuture.completedFuture(res); } @Override - public CompletableFuture> updateTodo(UpdateTodoEndpoint.Request request) { + public CompletableFuture> updateTodo(UpdateTodoEndpoint.Request request) { return null; } @Override - public CompletableFuture> getTodos(GetTodosEndpoint.Request request) { - var res = new GetTodosEndpoint.Response200ApplicationJson(service.store); + public CompletableFuture> getTodos(GetTodosEndpoint.Request request) { + var res = new GetTodosEndpoint.Response200(service.store); return CompletableFuture.completedFuture(res); } } diff --git a/fidle/bol/run.sh b/fidle/bol/run.sh deleted file mode 100644 index c5d93618a..000000000 --- a/fidle/bol/run.sh +++ /dev/null @@ -1 +0,0 @@ -../../src/plugin/cli/build/bin/macosArm64/releaseExecutable/cli.kexe convert OpenApiV3 -f "$(pwd)/fft.json" -l Kotlin \ No newline at end of file diff --git a/scripts/example.sh b/scripts/example.sh index d1d132fc0..67a97ccee 100755 --- a/scripts/example.sh +++ b/scripts/example.sh @@ -3,6 +3,7 @@ dir="$(dirname -- "$0")" ./gradlew jvmTest && + ./gradlew src:integration:spring:publishToMavenLocal && ./gradlew src:plugin:gradle:publishToMavenLocal && ./gradlew src:plugin:maven:publishToMavenLocal && (cd "$dir"/../src/ide/vscode && npm i && npm run build) && diff --git a/src/integration/spring/build.gradle.kts b/src/integration/spring/build.gradle.kts index 39c928995..9b0300026 100644 --- a/src/integration/spring/build.gradle.kts +++ b/src/integration/spring/build.gradle.kts @@ -31,8 +31,8 @@ kotlin { } val jvmMain by getting { dependencies { - compileOnly(project(":src:compiler:core")) compileOnly(project(":src:integration:wirespec")) + compileOnly(project(":src:compiler:core")) implementation(project(":src:integration:jackson")) implementation("org.springframework.boot:spring-boot-starter-web:3.2.3") implementation("org.jetbrains.kotlin:kotlin-reflect") diff --git a/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/java/emit/SpringJavaEmitter.kt b/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/java/emit/SpringJavaEmitter.kt index 5d0a07bda..0cf2585ae 100644 --- a/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/java/emit/SpringJavaEmitter.kt +++ b/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/java/emit/SpringJavaEmitter.kt @@ -1,19 +1,22 @@ package community.flock.wirespec.integration.spring.java.emit import community.flock.wirespec.compiler.core.emit.JavaEmitter -import community.flock.wirespec.compiler.core.emit.transformer.EndpointClass import community.flock.wirespec.compiler.core.parse.Endpoint import community.flock.wirespec.compiler.utils.Logger class SpringJavaEmitter(packageName: String, logger: Logger) : JavaEmitter(packageName, logger) { override fun emitHandleFunction(endpoint: Endpoint): String { val path = "/${endpoint.path.joinToString("/") { it.emit() }}" - return when (endpoint.method) { + val annotation = when (endpoint.method) { Endpoint.Method.GET -> "@org.springframework.web.bind.annotation.GetMapping(\"${path}\")\n" Endpoint.Method.POST -> "@org.springframework.web.bind.annotation.PostMapping(\"${path}\")\n" Endpoint.Method.PUT -> "@org.springframework.web.bind.annotation.PutMapping(\"${path}\")\n" Endpoint.Method.DELETE -> "@org.springframework.web.bind.annotation.DeleteMapping(\"${path}\")\n" else -> error("Method not implemented: ${endpoint.method}") } + return """ + |${annotation} + |${super.emitHandleFunction(endpoint)} + """.trimMargin() } } \ No newline at end of file diff --git a/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/configuration/WirespecConfiguration.kt b/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/configuration/WirespecConfiguration.kt index 4ea9ff665..77d1711bc 100644 --- a/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/configuration/WirespecConfiguration.kt +++ b/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/configuration/WirespecConfiguration.kt @@ -1,31 +1,35 @@ package community.flock.wirespec.integration.spring.kotlin.configuration import com.fasterxml.jackson.databind.ObjectMapper -import community.flock.wirespec.integration.jackson.java.WirespecModuleJava +import community.flock.wirespec.integration.jackson.kotlin.WirespecModuleKotlin import community.flock.wirespec.integration.spring.kotlin.web.WirespecResponseBodyAdvice -import community.flock.wirespec.java.Wirespec +import community.flock.wirespec.kotlin.Wirespec import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Import -import java.lang.reflect.Type +import kotlin.reflect.KType +import kotlin.reflect.javaType @Configuration @Import(WirespecResponseBodyAdvice::class, WirespecWebMvcConfiguration::class) +@OptIn(ExperimentalStdlibApi::class) open class WirespecConfiguration { @Bean open fun wirespecSerialization(objectMapper: ObjectMapper) = object : Wirespec.Serialization { - private val wirespecObjectMapper = objectMapper.copy().registerModule(WirespecModuleJava()) + private val wirespecObjectMapper = objectMapper.copy().registerModule(WirespecModuleKotlin()) - override fun serialize(body: T, type: Type?): String { + override fun serialize(body: T, kType: KType): String { return wirespecObjectMapper.writeValueAsString(body) } - override fun deserialize(raw: String?, valueType: Type?): T { - val type = wirespecObjectMapper.constructType(valueType) + override fun deserialize(raw: String, kType: KType): T { + val type = wirespecObjectMapper.constructType(kType.javaType) val obj: T = wirespecObjectMapper.readValue(raw, type) return obj } + + } } diff --git a/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/configuration/WirespecWebMvcConfiguration.kt b/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/configuration/WirespecWebMvcConfiguration.kt index 16eb164f9..0c2e03468 100644 --- a/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/configuration/WirespecWebMvcConfiguration.kt +++ b/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/configuration/WirespecWebMvcConfiguration.kt @@ -1,7 +1,7 @@ package community.flock.wirespec.integration.spring.kotlin.configuration -import community.flock.wirespec.integration.spring.java.web.WirespecMethodArgumentResolver -import community.flock.wirespec.java.Wirespec +import community.flock.wirespec.integration.spring.kotlin.web.WirespecMethodArgumentResolver +import community.flock.wirespec.kotlin.Wirespec import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Configuration import org.springframework.web.method.support.HandlerMethodArgumentResolver diff --git a/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/web/WirespecMethodArgumentResolver.kt b/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/web/WirespecMethodArgumentResolver.kt index fc1669983..441dd3512 100644 --- a/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/web/WirespecMethodArgumentResolver.kt +++ b/src/integration/spring/src/jvmMain/kotlin/community/flock/wirespec/integration/spring/kotlin/web/WirespecMethodArgumentResolver.kt @@ -1,20 +1,13 @@ package community.flock.wirespec.integration.spring.kotlin.web -import community.flock.wirespec.integration.spring.java.ExtensionFunctions.getStaticMethode -import community.flock.wirespec.integration.spring.java.ExtensionFunctions.invoke -import community.flock.wirespec.java.Wirespec -import jakarta.servlet.http.HttpServletRequest +import community.flock.wirespec.kotlin.Wirespec import org.springframework.core.MethodParameter -import org.springframework.http.server.PathContainer import org.springframework.web.bind.support.WebDataBinderFactory import org.springframework.web.context.request.NativeWebRequest import org.springframework.web.method.support.HandlerMethodArgumentResolver import org.springframework.web.method.support.ModelAndViewContainer -import org.springframework.web.util.pattern.PathPatternParser -import java.io.BufferedReader -import kotlin.reflect.full.companionObjectInstance -class WirespecMethodArgumentResolver(private val contentMapper: Wirespec.Serialization) : +class WirespecMethodArgumentResolver(private val wirespecSerialization: Wirespec.Serialization) : HandlerMethodArgumentResolver { override fun supportsParameter(parameter: MethodParameter): Boolean { diff --git a/src/plugin/maven/src/main/kotlin/CustomMojo.kt b/src/plugin/maven/src/main/kotlin/CustomMojo.kt index cff1cba4a..676a30ba3 100644 --- a/src/plugin/maven/src/main/kotlin/CustomMojo.kt +++ b/src/plugin/maven/src/main/kotlin/CustomMojo.kt @@ -12,12 +12,12 @@ import community.flock.wirespec.plugin.Language import community.flock.wirespec.plugin.PackageName import community.flock.wirespec.plugin.compile import community.flock.wirespec.plugin.toDirectory -import java.io.File import org.apache.maven.plugins.annotations.LifecyclePhase import org.apache.maven.plugins.annotations.Mojo import org.apache.maven.plugins.annotations.Parameter import org.apache.maven.plugins.annotations.ResolutionScope import org.apache.maven.project.MavenProject +import java.io.File @Mojo( name = "custom", @@ -43,13 +43,20 @@ class CustomMojo : BaseMojo() { val ext = extension val emitterPkg = PackageName(packageName) + val emitter = try { - getClassLoader(project) - .loadClass(emitterClass) - .getConstructor(String::class.java, Logger::class.java) - .newInstance(emitterPkg.value, logger) as Emitter -// .getConstructor(Logger::class.java, Boolean::class.java) -// .newInstance(logger, split) as Emitter + val clazz = getClassLoader(project).loadClass(emitterClass) + val constructor = clazz.constructors.first() + val args = constructor.parameters + .map { + when (it.type) { + String::class.java -> packageName + Boolean::class.java -> split + Logger::class.java -> logger + else -> error("Cannot map constructor parameter") + } + } + constructor.newInstance(*args.toTypedArray()) as Emitter } catch (e: Exception) { throw e.also { it.printStackTrace() } } @@ -78,6 +85,7 @@ class CustomMojo : BaseMojo() { private fun getClassLoader(project: MavenProject): ClassLoader { try { + val classpathElements = project.compileClasspathElements.apply { add(project.build.outputDirectory) add(project.build.testOutputDirectory) @@ -85,6 +93,7 @@ class CustomMojo : BaseMojo() { val urls = classpathElements.indices .map { File(classpathElements[it] as String).toURI().toURL() } .toTypedArray() + return java.net.URLClassLoader(urls, javaClass.getClassLoader()) } catch (e: Exception) { log.debug("Couldn't get the classloader.")