From c66a9af3ea02ba4860d349dd80824d49588da8af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6sle?= Date: Thu, 28 Aug 2025 15:41:17 +0200 Subject: [PATCH 1/9] feature: element template generation maven module --- documentation/documentation-api/pom.xml | 15 + .../api/ProcessEngineWorkerDocumentation.kt | 7 + ...rocessEngineWorkerPropertyDocumentation.kt | 8 + .../worker/documentation/api/PropertyType.kt | 7 + documentation/documentation-core/pom.xml | 92 +++ .../core/InputValueNamingPolicy.kt | 6 + .../documentation/core/TargetPlattform.kt | 5 + .../core/generator/BPMNElementType.kt | 7 + .../core/generator/DocumentationGenerator.kt | 62 ++ .../generator/EngineDocumentationGenerator.kt | 12 + .../core/generator/GenerationResult.kt | 11 + .../ProcessEngineWorkerDocumentationInfo.kt | 10 + .../ProcessEngineWorkerPropertyInfo.kt | 11 + .../c7/Camunda7ElementTemplateGenerator.kt | 192 +++++++ .../core/generator/engines/c7/SchemaMixin.kt | 9 + .../schema/camunda-c7-element-template.json | 540 ++++++++++++++++++ documentation/documentation-plugin/pom.xml | 74 +++ .../WorkerDocumentationGeneratorMojo.kt | 107 ++++ .../schema/camunda-c7-element-template.json | 540 ++++++++++++++++++ documentation/pom.xml | 21 + .../camunda7-documentation-example/README.md | 7 + .../camunda7-documentation-example/pom.xml | 60 ++ .../src/main/kotlin/worker/ExampleDto.kt | 9 + .../src/main/kotlin/worker/ExampleWorker.kt | 14 + .../element-templates/Example-Worker.json | 67 +++ examples/pom.xml | 1 + pom.xml | 1 + 27 files changed, 1895 insertions(+) create mode 100644 documentation/documentation-api/pom.xml create mode 100644 documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/ProcessEngineWorkerDocumentation.kt create mode 100644 documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/ProcessEngineWorkerPropertyDocumentation.kt create mode 100644 documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/PropertyType.kt create mode 100644 documentation/documentation-core/pom.xml create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/InputValueNamingPolicy.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/TargetPlattform.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/BPMNElementType.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/DocumentationGenerator.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/GenerationResult.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerDocumentationInfo.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerPropertyInfo.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/SchemaMixin.kt create mode 100644 documentation/documentation-core/src/main/resources/schema/camunda-c7-element-template.json create mode 100644 documentation/documentation-plugin/pom.xml create mode 100644 documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt create mode 100644 documentation/documentation-plugin/src/main/resources/schema/camunda-c7-element-template.json create mode 100644 documentation/pom.xml create mode 100644 examples/camunda7-documentation-example/README.md create mode 100644 examples/camunda7-documentation-example/pom.xml create mode 100644 examples/camunda7-documentation-example/src/main/kotlin/worker/ExampleDto.kt create mode 100644 examples/camunda7-documentation-example/src/main/kotlin/worker/ExampleWorker.kt create mode 100644 examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json diff --git a/documentation/documentation-api/pom.xml b/documentation/documentation-api/pom.xml new file mode 100644 index 0000000..ef8954c --- /dev/null +++ b/documentation/documentation-api/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation + 0.6.1-SNAPSHOT + + + process-engine-worker-documentation-api + ${artifactId} + + diff --git a/documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/ProcessEngineWorkerDocumentation.kt b/documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/ProcessEngineWorkerDocumentation.kt new file mode 100644 index 0000000..212e3b0 --- /dev/null +++ b/documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/ProcessEngineWorkerDocumentation.kt @@ -0,0 +1,7 @@ +package dev.bpmcrafters.processengine.worker.documentation.api + +annotation class ProcessEngineWorkerDocumentation( + val name: String, + val description: String = "", + val version: Int = -1 +) diff --git a/documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/ProcessEngineWorkerPropertyDocumentation.kt b/documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/ProcessEngineWorkerPropertyDocumentation.kt new file mode 100644 index 0000000..3e4fdd8 --- /dev/null +++ b/documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/ProcessEngineWorkerPropertyDocumentation.kt @@ -0,0 +1,8 @@ +package dev.bpmcrafters.processengine.worker.documentation.api + +annotation class ProcessEngineWorkerPropertyDocumentation( + val type: PropertyType = PropertyType.STRING, + val label: String, + val notEmpty: Boolean = false, + val editable: Boolean = true, +) diff --git a/documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/PropertyType.kt b/documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/PropertyType.kt new file mode 100644 index 0000000..0f82111 --- /dev/null +++ b/documentation/documentation-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/api/PropertyType.kt @@ -0,0 +1,7 @@ +package dev.bpmcrafters.processengine.worker.documentation.api + +enum class PropertyType(val type: String) { + STRING("String"), + TEXT("Text"), + HIDDEN("Hidden") +} diff --git a/documentation/documentation-core/pom.xml b/documentation/documentation-core/pom.xml new file mode 100644 index 0000000..d7aacdb --- /dev/null +++ b/documentation/documentation-core/pom.xml @@ -0,0 +1,92 @@ + + + 4.0.0 + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation + 0.6.1-SNAPSHOT + + + process-engine-worker-documentation-core + ${artifactId} + + + 3.9.11 + 3.15.1 + 0.10.2 + 3.15.1 + + + + + org.reflections + reflections + ${org.reflections.version} + + + + + org.apache.maven + maven-plugin-api + ${org.apache.maven.version} + + + + org.apache.maven + maven-core + ${org.apache.maven.version} + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${org.apache.maven.plugin-tools.version} + provided + + + + commons-io + commons-io + 2.20.0 + + + + dev.bpm-crafters.process-engine-worker + process-engine-worker-spring-boot-starter + ${project.version} + + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-api + ${project.version} + + + + + + + org.jsonschema2pojo + jsonschema2pojo-maven-plugin + 1.2.2 + + ${basedir}/src/main/resources/schema + dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen + true + true + + + + generate-sources + + generate + + + + + + + + + diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/InputValueNamingPolicy.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/InputValueNamingPolicy.kt new file mode 100644 index 0000000..e8a4ed1 --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/InputValueNamingPolicy.kt @@ -0,0 +1,6 @@ +package dev.bpmcrafters.processengine.worker.documentation.core + +enum class InputValueNamingPolicy { + EMPTY, + ATTRIBUTE_NAME +} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/TargetPlattform.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/TargetPlattform.kt new file mode 100644 index 0000000..5caedd9 --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/TargetPlattform.kt @@ -0,0 +1,5 @@ +package dev.bpmcrafters.processengine.worker.documentation.core + +enum class TargetPlattform { + C7 +} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/BPMNElementType.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/BPMNElementType.kt new file mode 100644 index 0000000..992d032 --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/BPMNElementType.kt @@ -0,0 +1,7 @@ +package dev.bpmcrafters.processengine.worker.documentation.core.generator + +enum class BPMNElementType(val value: String) { + BPMN_SERVICE_TASK("bpmn:ServiceTask"), + BPMN_SEND_TASK("bpmn:SendTask"), + BPMN_INTERMEDIATE_THROW_EVENT("bpmn:IntermediateThrowEvent") +} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/DocumentationGenerator.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/DocumentationGenerator.kt new file mode 100644 index 0000000..9faa1cb --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/DocumentationGenerator.kt @@ -0,0 +1,62 @@ +package dev.bpmcrafters.processengine.worker.documentation.core.generator + +import dev.bpmcrafters.processengine.worker.ProcessEngineWorker +import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerDocumentation +import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerPropertyDocumentation +import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy +import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform +import dev.bpmcrafters.processengine.worker.documentation.core.generator.engines.c7.Camunda7ElementTemplateGenerator +import org.apache.commons.io.FileUtils +import java.io.File + +class DocumentationGenerator( + val outputPath: File, + val engine: TargetPlattform, + val namingPolicy: InputValueNamingPolicy = InputValueNamingPolicy.EMPTY +) { + + val engineDocumentationGenerators = listOf( + Camunda7ElementTemplateGenerator() + ) + + fun generate( + workerAnnotation: ProcessEngineWorker, + documentationAnnotation: ProcessEngineWorkerDocumentation, + parameter: Class<*>, + returnType: Class<*> + ) { + val processEngineWorkerDocumentation = ProcessEngineWorkerDocumentationInfo( + documentationAnnotation.name, + documentationAnnotation.description, + documentationAnnotation.version, + workerAnnotation.topic, + generateProperties(parameter), + generateProperties(returnType) + ) + + val engine = engineDocumentationGenerators + .filter { it.isSupported(engine) } + .let { if (it.size != 1) throw RuntimeException("Expected exactly one engine documentation generator for $engine, but got ${it.size}") else it.first() } + + val result = engine.generate(processEngineWorkerDocumentation, namingPolicy) + + FileUtils.createParentDirectories(outputPath) + + val workerDocumentation = File(outputPath, result.fileName) + FileUtils.write(workerDocumentation, result.content, "UTF-8") + } + + private fun generateProperties(type: Class<*>): List { + return type.declaredFields.map { field -> + val annotation = field.getAnnotation(ProcessEngineWorkerPropertyDocumentation::class.java) + ProcessEngineWorkerPropertyInfo( + name = field.name, + label = annotation.label, + type = annotation.type, + editable = annotation.editable, + notEmpty = annotation.notEmpty, + ) + } + } + +} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt new file mode 100644 index 0000000..753ebc7 --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt @@ -0,0 +1,12 @@ +package dev.bpmcrafters.processengine.worker.documentation.core.generator + +import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy +import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform + +interface EngineDocumentationGenerator { + + fun generate(processEngineWorkerDocumentationInfo: ProcessEngineWorkerDocumentationInfo, namingPolicy: InputValueNamingPolicy): GenerationResult + + fun isSupported(targetPlattform: TargetPlattform): Boolean + +} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/GenerationResult.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/GenerationResult.kt new file mode 100644 index 0000000..e13647e --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/GenerationResult.kt @@ -0,0 +1,11 @@ +package dev.bpmcrafters.processengine.worker.documentation.core.generator + +import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform + +data class GenerationResult( + val name: String, + val version : Int, + val content: String, + val fileName: String, + val engine: TargetPlattform +) diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerDocumentationInfo.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerDocumentationInfo.kt new file mode 100644 index 0000000..86f76bc --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerDocumentationInfo.kt @@ -0,0 +1,10 @@ +package dev.bpmcrafters.processengine.worker.documentation.core.generator + +data class ProcessEngineWorkerDocumentationInfo( + val name: String, + val description: String, + val version: Int, + val type: String, + val inputProperties: List, + val outputProperties: List +) diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerPropertyInfo.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerPropertyInfo.kt new file mode 100644 index 0000000..dc0027e --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerPropertyInfo.kt @@ -0,0 +1,11 @@ +package dev.bpmcrafters.processengine.worker.documentation.core.generator + +import dev.bpmcrafters.processengine.worker.documentation.api.PropertyType + +data class ProcessEngineWorkerPropertyInfo( + val name: String, + val label: String, + val type: PropertyType, + val editable: Boolean, + val notEmpty: Boolean, +) diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt new file mode 100644 index 0000000..155641f --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt @@ -0,0 +1,192 @@ +package dev.bpmcrafters.processengine.worker.documentation.core.generator.engines.c7 + +import com.fasterxml.jackson.core.JsonProcessingException +import com.fasterxml.jackson.databind.MapperFeature +import com.fasterxml.jackson.databind.json.JsonMapper +import dev.bpmcrafters.processengine.worker.documentation.api.PropertyType +import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen.Binding +import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen.CamundaC7ElementTemplate +import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen.Constraints +import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen.Property +import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy +import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform +import dev.bpmcrafters.processengine.worker.documentation.core.generator.* + +class Camunda7ElementTemplateGenerator: EngineDocumentationGenerator { + override fun generate(processEngineWorkerDocumentationInfo: ProcessEngineWorkerDocumentationInfo, namingPolicy: InputValueNamingPolicy): GenerationResult { + val elementTemplate = CamundaC7ElementTemplate() + .withName(processEngineWorkerDocumentationInfo.name) + .withId(processEngineWorkerDocumentationInfo.type) + .withAppliesTo(mutableListOf(BPMNElementType.BPMN_SERVICE_TASK.value)) + + if (processEngineWorkerDocumentationInfo.version > 0) { + elementTemplate.version = processEngineWorkerDocumentationInfo.version as Double + } + + + // Add external task property + val implementationProperty = createExternalTaskProperty() + elementTemplate.properties.add(implementationProperty) + + + // Add property for the topic of the external task + val implementationTopicProperty = createExternalTaskTopicProperty(processEngineWorkerDocumentationInfo.type) + elementTemplate.properties.add(implementationTopicProperty) + + + // Add asyncBefore property + val asyncBeforeProperty = createAsyncBeforeProperty() + elementTemplate.properties.add(asyncBeforeProperty) + + + // Add asyncAfter property + val asyncAfterProperty = createAsyncAfterProperty() + elementTemplate.properties.add(asyncAfterProperty) + + + // Add properties for input parameters + for (inputProperty in processEngineWorkerDocumentationInfo.inputProperties) { + val property = createInputParameterProp(inputProperty, namingPolicy) + elementTemplate.properties.add(property) + } + + + // Add properties for output parameters + for (outputProperties in processEngineWorkerDocumentationInfo.outputProperties) { + val property = createOutputParameterProp(outputProperties) + elementTemplate.properties.add(property) + } + + val json = toJsonString(elementTemplate) + return GenerationResult( + name = processEngineWorkerDocumentationInfo.name, + version = processEngineWorkerDocumentationInfo.version, + content = json, + fileName = processEngineWorkerDocumentationInfo.name.replace(" ", "-") + ".json", + engine = TargetPlattform.C7 + ) + } + + override fun isSupported(targetPlattform: TargetPlattform): Boolean { + return TargetPlattform.C7 == targetPlattform + } + + private fun createInputParameterProp( + info: ProcessEngineWorkerPropertyInfo, + inputValueNamingPolicy: InputValueNamingPolicy + ): Property { + val property = Property() + .withLabel("Input: ${info.label}") + .withValue( + when (inputValueNamingPolicy) { + InputValueNamingPolicy.EMPTY -> "\${}" + InputValueNamingPolicy.ATTRIBUTE_NAME -> "\${${info.name}}" + } + ) + .withType(info.type.type) + .withChoices(null) + .withBinding( + Binding() + .withType(Binding.Type.CAMUNDA_INPUT_PARAMETER) + .withName(info.name) + ) + property.constraints = Constraints() + .withNotEmpty(info.notEmpty) + property.editable = info.editable + + return property + } + + private fun createOutputParameterProp(info: ProcessEngineWorkerPropertyInfo): Property { + val property = Property() + .withLabel("Output: ${info.label}") + .withValue(info.name) + .withType(info.type.type) + .withChoices(null) + .withBinding( + Binding() + .withType(Binding.Type.CAMUNDA_OUTPUT_PARAMETER) + .withSource("\${${info.name}}") + ) + property.constraints = Constraints() + .withNotEmpty(info.notEmpty) + property.editable = info.editable + + return property + } + + private fun createExternalTaskProperty(): Property { + return Property() + .withLabel("Implementation Type") + .withType(PropertyType.STRING.type) + .withValue("external") + .withEditable(false) + // See Java comment: avoid empty list in JSON by setting choices to null + .withChoices(null) + .withBinding( + Binding() + .withType(Binding.Type.PROPERTY) + .withName("camunda:type") + ) + } + + private fun createExternalTaskTopicProperty(type: String): Property { + return Property() + .withLabel("Topic") + .withType(PropertyType.STRING.type) + .withValue(type) + .withEditable(false) + .withChoices(null) + .withBinding( + Binding() + .withType(Binding.Type.PROPERTY) + .withName("camunda:topic") + ) + } + + // TODO async before should be configurable + private fun createAsyncBeforeProperty(): Property { + return Property() + .withLabel("Async Before") + .withType("Boolean") + .withValue(false) + .withEditable(true) + .withChoices(null) + .withBinding( + Binding() + .withType(Binding.Type.PROPERTY) + .withName("camunda:asyncBefore") + ) + } + + // TODO async before should be configurable + private fun createAsyncAfterProperty(): Property { + return Property() + .withLabel("Async After") + .withType("Boolean") + .withValue(false) + .withEditable(true) + .withChoices(null) + .withBinding( + Binding() + .withType(Binding.Type.PROPERTY) + .withName("camunda:asyncAfter") + ) + } + + private fun toJsonString(elementTemplate: CamundaC7ElementTemplate): String { + try { + val jsonSchema = "https://unpkg.com/@camunda/element-templates-json-schema@0.1.0/resources/schema.json" + val mapper = JsonMapper.builder() + .configure(MapperFeature.SORT_CREATOR_PROPERTIES_FIRST, true) + .addMixIn(CamundaC7ElementTemplate::class.java, SchemaMixin::class.java) + .build() + val objectWriter = mapper.writerFor(CamundaC7ElementTemplate::class.java) + .withAttribute("\$schema", jsonSchema) + return objectWriter.withDefaultPrettyPrinter().writeValueAsString(elementTemplate) + } catch (e: JsonProcessingException) { + throw RuntimeException("Could not generate json string!", e) + } + } + +} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/SchemaMixin.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/SchemaMixin.kt new file mode 100644 index 0000000..0c455b7 --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/SchemaMixin.kt @@ -0,0 +1,9 @@ +package dev.bpmcrafters.processengine.worker.documentation.core.generator.engines.c7 + +import com.fasterxml.jackson.databind.annotation.JsonAppend + +@JsonAppend(attrs = [JsonAppend.Attr(value = "\$schema")], prepend = true) +class SchemaMixin { + // Because the generated element template does not have a property to + // set the schema, we add it manually on serialization +} diff --git a/documentation/documentation-core/src/main/resources/schema/camunda-c7-element-template.json b/documentation/documentation-core/src/main/resources/schema/camunda-c7-element-template.json new file mode 100644 index 0000000..538ec46 --- /dev/null +++ b/documentation/documentation-core/src/main/resources/schema/camunda-c7-element-template.json @@ -0,0 +1,540 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://camunda.org/schema/element-templates/1.0", + "type": "object", + "title": "Element Template Schema", + "description": "An element template definition", + "required": [ + "name", + "id", + "appliesTo", + "properties" + ], + "properties": { + "name": { + "$id": "#/name", + "type": "string", + "title": "element template name", + "description": "The name of the element template" + }, + "id": { + "$id": "#/id", + "type": "string", + "title": "element template id", + "description": "The identifier of the element template" + }, + "description": { + "$id": "#/description", + "type": "string", + "title": "element template description", + "description": "The description of the element template" + }, + "version": { + "$id": "#/version", + "type": "number", + "title": "element template version", + "description": "The version of the element template" + }, + "isDefault": { + "$id": "#/isDefault", + "type": "boolean", + "title": "element template is default", + "description": "Indicates whether the element template is a default template" + }, + "appliesTo": { + "$id": "#/appliesTo", + "type": "array", + "title": "element template applies to", + "description": "The definition for which element types the element template can be applied", + "default": [], + "items": { + "$id": "#/appliesTo/items", + "type": "string", + "pattern": "^(bpmn:)" + } + }, + "properties": { + "$id": "#/properties", + "type": "array", + "title": "element template properties", + "description": "The properties of the element template", + "default": [], + "items": { + "$id": "#/properties/property", + "type": "object", + "title": "element template property", + "description": "A property defined for the element template", + "default": {}, + "required": [ + "binding" + ], + "allOf": [ + { + "if": { + "properties": { + "type": { + "const": "Dropdown" + } + }, + "required": [ + "type" + ] + }, + "then": { + "required": [ + "choices" + ], + "errorMessage": "must provide choices=[] with \"Dropdown\" type" + } + }, + { + "if": { + "properties": { + "binding": { + "properties": { + "type": { + "const": "property" + } + }, + "required": [ + "type" + ] + } + }, + "required": [ + "binding" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "String", + "Text", + "Hidden", + "Dropdown", + "Boolean" + ], + "errorMessage": "invalid property type ${0} for binding type \"property\"; must be any of { String, Text, Hidden, Dropdown, Boolean }" + } + } + } + }, + { + "if": { + "properties": { + "binding": { + "properties": { + "type": { + "const": "camunda:executionListener" + } + }, + "required": [ + "type" + ] + } + }, + "required": [ + "binding" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "Hidden" + ], + "errorMessage": "invalid property type ${0} for binding type \"camunda:executionListener\"; must be \"Hidden\"" + } + } + } + }, + { + "if": { + "properties": { + "binding": { + "properties": { + "type": { + "enum": [ + "camunda:property", + "camunda:outputParameter", + "camunda:in", + "camunda:in:businessKey", + "camunda:out" + ] + } + }, + "required": [ + "type" + ] + } + }, + "required": [ + "binding" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "String", + "Hidden", + "Dropdown" + ], + "errorMessage": "invalid property type ${0} for binding type ${1/binding/type}; must be any of { String, Hidden, Dropdown }" + } + } + } + }, + { + "if": { + "properties": { + "binding": { + "properties": { + "type": { + "enum": [ + "camunda:inputParameter", + "camunda:field" + ] + } + }, + "required": [ + "type" + ] + } + }, + "required": [ + "binding" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "String", + "Text", + "Hidden", + "Dropdown" + ], + "errorMessage": "invalid property type ${0} for binding type ${1/binding/type}; must be any of { String, Text, Hidden, Dropdown }" + } + } + } + } + ], + "properties": { + "value": { + "$id": "#/properties/property/value", + "type": [ + "string", + "boolean" + ], + "title": "property value", + "description": "The value of the control field for the property" + }, + "description": { + "$id": "#/properties/property/description", + "type": "string", + "title": "property description", + "description": "The description of the control field" + }, + "label": { + "$id": "#/properties/property/label", + "type": "string", + "title": "property label", + "description": "The label of the control field for the property" + }, + "type": { + "$id": "#/properties/property/type", + "type": "string", + "title": "property type", + "description": "The type of the control field" + }, + "editable": { + "$id": "#/properties/property/editable", + "type": "boolean", + "title": "property editable", + "description": "Indicates whether the property is editable or not" + }, + "choices": { + "$id": "#/properties/property/choices", + "type": "array", + "title": "property choices", + "description": "The choices for dropdown properties", + "items": { + "$id": "#/properties/property/choices/item", + "type": "object", + "properties": { + "name": { + "$id": "#/properties/property/choices/item/name", + "type": "string", + "title": "choice name", + "description": "The name of the choice" + }, + "value": { + "$id": "#/properties/property/choices/item/value", + "type": "string", + "title": "choice value", + "description": "The value of the choice" + } + }, + "required": [ + "value", + "name" + ], + "errorMessage": "{ name, value } must be specified for \"Dropdown\" choices" + } + }, + "binding": { + "$id": "#/properties/property/binding", + "type": "object", + "title": "property binding", + "description": "A binding to a BPMN 2.0 property", + "required": [ + "type" + ], + "allOf": [ + { + "if": { + "properties": { + "type": { + "enum": [ + "property", + "camunda:property", + "camunda:inputParameter", + "camunda:field" + ] + } + }, + "required": [ + "type" + ] + }, + "then": { + "required": [ + "name" + ], + "errorMessage": "property.binding ${0/type} requires name" + } + }, + { + "if": { + "properties": { + "type": { + "const": "camunda:outputParameter" + } + }, + "required": [ + "type" + ] + }, + "then": { + "required": [ + "source" + ], + "errorMessage": "property.binding ${0/type} requires source" + } + }, + { + "if": { + "properties": { + "type": { + "const": "camunda:in" + } + }, + "required": [ + "type" + ] + }, + "then": { + "oneOf": [ + { + "required": [ + "variables" + ] + }, + { + "required": [ + "target" + ] + } + ], + "errorMessage": "property.binding ${0/type} requires variables or target" + } + }, + { + "if": { + "properties": { + "type": { + "const": "camunda:out" + } + }, + "required": [ + "type" + ] + }, + "then": { + "oneOf": [ + { + "required": [ + "variables" + ] + }, + { + "required": [ + "source" + ] + }, + { + "required": [ + "sourceExpression" + ] + } + ], + "errorMessage": "property.binding ${0/type} requires variables, sourceExpression or source" + } + } + ], + "properties": { + "type": { + "$id": "#/properties/property/binding/type", + "type": "string", + "title": "property binding type", + "enum": [ + "property", + "camunda:property", + "camunda:inputParameter", + "camunda:outputParameter", + "camunda:in", + "camunda:out", + "camunda:in:businessKey", + "camunda:executionListener", + "camunda:field" + ], + "errorMessage": "invalid property.binding type ${0}; must be any of { property, camunda:property, camunda:inputParameter, camunda:outputParameter, camunda:in, camunda:out, camunda:in:businessKey, camunda:executionListener, camunda:field }", + "description": "The type of the property binding" + }, + "name": { + "$id": "#/properties/property/binding/name", + "type": "string", + "title": "property binding name", + "description": "The name of binding xml property" + }, + "event": { + "$id": "#/properties/property/binding/event", + "type": "string", + "title": "property binding event", + "description": "The event type of an execution listener binding" + }, + "scriptFormat": { + "$id": "#/properties/property/binding/scriptFormat", + "type": "string", + "title": "property binding script format", + "description": "The format of a script property binding (camunda:outputParameter, camunda:inputParameter)" + }, + "source": { + "$id": "#/properties/property/binding/source", + "type": "string", + "title": "property binding source", + "description": "The source value of a property binding (camunda:outputParameter, camunda:out)" + }, + "target": { + "$id": "#/properties/property/binding/target", + "type": "string", + "title": "property binding target", + "description": "The target value to be mapped to (camunda:in)" + }, + "expression": { + "$id": "#/properties/property/binding/expression", + "type": "boolean", + "title": "property binding expression", + "description": "True indicates that the control field value is an expression (camunda:in, camunda:field)" + }, + "variables": { + "$id": "#/properties/property/binding/variables", + "type": "string", + "title": "property binding variables", + "enum": [ + "all", + "local" + ], + "description": "Either all or local indicating the variable mapping (camunda:in)" + }, + "sourceExpression": { + "$id": "#/properties/property/binding/sourceExpression", + "type": "string", + "title": "property binding source expression", + "description": "The string containing the expression for the source attribute (camunda:out)" + } + } + }, + "constraints": { + "$id": "#/properties/property/constraints", + "type": "object", + "title": "property constraints", + "description": "The validation constraints", + "properties": { + "notEmpty": { + "$id": "#/properties/property/constraints/notEmpty", + "type": "boolean", + "title": "property constraints not empty", + "description": "The control field must not be empty" + }, + "minLength": { + "$id": "#/properties/property/constraints/minLength", + "type": "string", + "title": "property constraints min length", + "description": "The minimal length for the control field value" + }, + "maxLength": { + "$id": "#/properties/property/constraints/maxLength", + "type": "string", + "title": "property constraints max length", + "description": "The maximal length for the control field value" + }, + "pattern": { + "$id": "#/properties/property/constraints/pattern", + "type": "object", + "title": "property constraints pattern", + "description": "A regular expression pattern for the constraints", + "properties": { + "value": { + "$id": "#/properties/property/constraints/pattern/value", + "type": "string", + "title": "property constraints pattern value", + "description": "The regular expression of the pattern constraint" + }, + "message": { + "$id": "#/properties/property/constraints/pattern/message", + "type": "string", + "title": "property constraints pattern message", + "description": "The validation message of the pattern constraint" + } + } + } + } + } + } + } + }, + "metadata": { + "$id": "#/metadata", + "type": "object", + "title": "element template metadata", + "description": "Some metadata for further configuration" + }, + "scopes": { + "$id": "#/scopes", + "type": "object", + "title": "element template scope", + "description": "Special scoped bindings that allow you to configure nested elements" + }, + "entriesVisible": { + "$id": "#/entriesVisible", + "deprecated": true, + "type": "object", + "title": "element template entries visible", + "description": "@Deprecated - Select which entries are visible in the properties panel" + } + } +} \ No newline at end of file diff --git a/documentation/documentation-plugin/pom.xml b/documentation/documentation-plugin/pom.xml new file mode 100644 index 0000000..09f6580 --- /dev/null +++ b/documentation/documentation-plugin/pom.xml @@ -0,0 +1,74 @@ + + + 4.0.0 + + dev.bpm-crafters.process-engine-worker + process-engine-worker-root + 0.6.1-SNAPSHOT + + + process-engine-worker-documentation-maven-plugin + ${project.artifactId} + maven-plugin + Maven plugin to generate element templates + + + 3.9.11 + 3.15.1 + 0.10.2 + 3.15.1 + + + + + + org.apache.maven + maven-plugin-api + ${org.apache.maven.version} + + + + org.apache.maven + maven-core + ${org.apache.maven.version} + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${org.apache.maven.plugin-tools.version} + provided + + + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-core + ${project.version} + + + + + + + org.apache.maven.plugins + maven-plugin-plugin + ${org.apache.maven-plugins.version} + + + + + + + + + org.apache.maven.plugins + maven-plugin-plugin + ${org.apache.maven-plugins.version} + + + + + + diff --git a/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt b/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt new file mode 100644 index 0000000..0f25058 --- /dev/null +++ b/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt @@ -0,0 +1,107 @@ +package dev.bpmcrafters.processengine.worker.documentation + +import dev.bpmcrafters.processengine.worker.ProcessEngineWorker +import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerDocumentation +import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy +import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform +import dev.bpmcrafters.processengine.worker.documentation.core.generator.DocumentationGenerator +import org.apache.commons.io.FileUtils +import org.apache.maven.plugin.AbstractMojo +import org.apache.maven.plugin.MojoExecutionException +import org.apache.maven.plugin.logging.Log +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 org.reflections.Reflections +import org.reflections.scanners.Scanners +import org.reflections.util.ClasspathHelper +import org.reflections.util.ConfigurationBuilder +import java.io.File +import java.io.IOException +import java.net.URL +import java.net.URLClassLoader + +@Mojo(name = "generate", defaultPhase = LifecyclePhase.PROCESS_CLASSES, requiresDependencyResolution = ResolutionScope.RUNTIME) +class WorkerDocumentationGeneratorMojo: AbstractMojo() { + + private val log: Log = getLog() + + @Parameter(defaultValue = "\${project}", required = true, readonly = true) + var project: MavenProject? = null + + /** + * The target platform for which goal should be executed. + */ + @Parameter(name = "targetPlatform", property = "elementtemplategen.targetPlatform", required = true) + var targetPlatform: TargetPlattform? = null + + /** + * Directory to output the generated element templates to. + */ + @Parameter(property = "elementtemplategen.outputDirectory", defaultValue = "\${project.build.directory/generated-sources/element-templates}") + var outputDirectory: File? = null + + /** + * The naming policy for input values. + * EMPTY => ${} + * ATTRIBUTE_NAME => ${} + */ + @Parameter(name = "inputValueNamingPolicy", property = "elementtemplategen.inputValueNamingPolicy", defaultValue = "EMPTY") + var inputValueNamingPolicy: InputValueNamingPolicy? = null + + /** + * A flag indicating if the output directory should be cleaned before generation. + */ + @Parameter(name = "clean", property = "elementtemplategen.clean", defaultValue = "false") + var clean: Boolean = false + + override fun execute() { + log.info("Generating element templates for ${project?.artifactId}") + + // Clean output directory + if (clean) { + try { + log.info("Cleaning output directory...") + FileUtils.deleteDirectory(outputDirectory) + } catch(e: IOException) { + log.error("Failed to clean output directory.", e) + throw MojoExecutionException("Failed to clean output directory.", e) + } + } + + // Find annotated workers + val classpathURLs = project!!.compileClasspathElements + .map { File(it).toURI().toURL() } + val urlClassLoader = URLClassLoader(classpathURLs.toTypedArray(), javaClass.getClassLoader()) + val reflections = Reflections( + ConfigurationBuilder() + .setUrls(ClasspathHelper.forClassLoader(urlClassLoader)) + .addClassLoaders(urlClassLoader) + .addScanners(Scanners.MethodsAnnotated) + ) + val workers = reflections.getMethodsAnnotatedWith(ProcessEngineWorker::class.java) + val generator = DocumentationGenerator(outputDirectory!!, targetPlatform!!, inputValueNamingPolicy!!) + + // generate documentation for each worker + workers.forEach({ + val inputParams = it.parameterTypes + + if (inputParams.size > 1) { + throw MojoExecutionException("Worker method ${it.name} has more than one parameter.") + } + + try { + val workerAnnotation = it.getAnnotation(ProcessEngineWorker::class.java) + val documentationAnnotation = it.getAnnotation(ProcessEngineWorkerDocumentation::class.java) + + generator.generate(workerAnnotation, documentationAnnotation, inputParams.first(), it.returnType) + } catch(e: NullPointerException) { + log.error("Worker method ${it.name} is missing required annotation.", e) + throw MojoExecutionException("Worker method ${it.name} is missing @ProcessEngineWorkerDocumentation annotation.") + } + }) + } + +} diff --git a/documentation/documentation-plugin/src/main/resources/schema/camunda-c7-element-template.json b/documentation/documentation-plugin/src/main/resources/schema/camunda-c7-element-template.json new file mode 100644 index 0000000..538ec46 --- /dev/null +++ b/documentation/documentation-plugin/src/main/resources/schema/camunda-c7-element-template.json @@ -0,0 +1,540 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://camunda.org/schema/element-templates/1.0", + "type": "object", + "title": "Element Template Schema", + "description": "An element template definition", + "required": [ + "name", + "id", + "appliesTo", + "properties" + ], + "properties": { + "name": { + "$id": "#/name", + "type": "string", + "title": "element template name", + "description": "The name of the element template" + }, + "id": { + "$id": "#/id", + "type": "string", + "title": "element template id", + "description": "The identifier of the element template" + }, + "description": { + "$id": "#/description", + "type": "string", + "title": "element template description", + "description": "The description of the element template" + }, + "version": { + "$id": "#/version", + "type": "number", + "title": "element template version", + "description": "The version of the element template" + }, + "isDefault": { + "$id": "#/isDefault", + "type": "boolean", + "title": "element template is default", + "description": "Indicates whether the element template is a default template" + }, + "appliesTo": { + "$id": "#/appliesTo", + "type": "array", + "title": "element template applies to", + "description": "The definition for which element types the element template can be applied", + "default": [], + "items": { + "$id": "#/appliesTo/items", + "type": "string", + "pattern": "^(bpmn:)" + } + }, + "properties": { + "$id": "#/properties", + "type": "array", + "title": "element template properties", + "description": "The properties of the element template", + "default": [], + "items": { + "$id": "#/properties/property", + "type": "object", + "title": "element template property", + "description": "A property defined for the element template", + "default": {}, + "required": [ + "binding" + ], + "allOf": [ + { + "if": { + "properties": { + "type": { + "const": "Dropdown" + } + }, + "required": [ + "type" + ] + }, + "then": { + "required": [ + "choices" + ], + "errorMessage": "must provide choices=[] with \"Dropdown\" type" + } + }, + { + "if": { + "properties": { + "binding": { + "properties": { + "type": { + "const": "property" + } + }, + "required": [ + "type" + ] + } + }, + "required": [ + "binding" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "String", + "Text", + "Hidden", + "Dropdown", + "Boolean" + ], + "errorMessage": "invalid property type ${0} for binding type \"property\"; must be any of { String, Text, Hidden, Dropdown, Boolean }" + } + } + } + }, + { + "if": { + "properties": { + "binding": { + "properties": { + "type": { + "const": "camunda:executionListener" + } + }, + "required": [ + "type" + ] + } + }, + "required": [ + "binding" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "Hidden" + ], + "errorMessage": "invalid property type ${0} for binding type \"camunda:executionListener\"; must be \"Hidden\"" + } + } + } + }, + { + "if": { + "properties": { + "binding": { + "properties": { + "type": { + "enum": [ + "camunda:property", + "camunda:outputParameter", + "camunda:in", + "camunda:in:businessKey", + "camunda:out" + ] + } + }, + "required": [ + "type" + ] + } + }, + "required": [ + "binding" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "String", + "Hidden", + "Dropdown" + ], + "errorMessage": "invalid property type ${0} for binding type ${1/binding/type}; must be any of { String, Hidden, Dropdown }" + } + } + } + }, + { + "if": { + "properties": { + "binding": { + "properties": { + "type": { + "enum": [ + "camunda:inputParameter", + "camunda:field" + ] + } + }, + "required": [ + "type" + ] + } + }, + "required": [ + "binding" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "String", + "Text", + "Hidden", + "Dropdown" + ], + "errorMessage": "invalid property type ${0} for binding type ${1/binding/type}; must be any of { String, Text, Hidden, Dropdown }" + } + } + } + } + ], + "properties": { + "value": { + "$id": "#/properties/property/value", + "type": [ + "string", + "boolean" + ], + "title": "property value", + "description": "The value of the control field for the property" + }, + "description": { + "$id": "#/properties/property/description", + "type": "string", + "title": "property description", + "description": "The description of the control field" + }, + "label": { + "$id": "#/properties/property/label", + "type": "string", + "title": "property label", + "description": "The label of the control field for the property" + }, + "type": { + "$id": "#/properties/property/type", + "type": "string", + "title": "property type", + "description": "The type of the control field" + }, + "editable": { + "$id": "#/properties/property/editable", + "type": "boolean", + "title": "property editable", + "description": "Indicates whether the property is editable or not" + }, + "choices": { + "$id": "#/properties/property/choices", + "type": "array", + "title": "property choices", + "description": "The choices for dropdown properties", + "items": { + "$id": "#/properties/property/choices/item", + "type": "object", + "properties": { + "name": { + "$id": "#/properties/property/choices/item/name", + "type": "string", + "title": "choice name", + "description": "The name of the choice" + }, + "value": { + "$id": "#/properties/property/choices/item/value", + "type": "string", + "title": "choice value", + "description": "The value of the choice" + } + }, + "required": [ + "value", + "name" + ], + "errorMessage": "{ name, value } must be specified for \"Dropdown\" choices" + } + }, + "binding": { + "$id": "#/properties/property/binding", + "type": "object", + "title": "property binding", + "description": "A binding to a BPMN 2.0 property", + "required": [ + "type" + ], + "allOf": [ + { + "if": { + "properties": { + "type": { + "enum": [ + "property", + "camunda:property", + "camunda:inputParameter", + "camunda:field" + ] + } + }, + "required": [ + "type" + ] + }, + "then": { + "required": [ + "name" + ], + "errorMessage": "property.binding ${0/type} requires name" + } + }, + { + "if": { + "properties": { + "type": { + "const": "camunda:outputParameter" + } + }, + "required": [ + "type" + ] + }, + "then": { + "required": [ + "source" + ], + "errorMessage": "property.binding ${0/type} requires source" + } + }, + { + "if": { + "properties": { + "type": { + "const": "camunda:in" + } + }, + "required": [ + "type" + ] + }, + "then": { + "oneOf": [ + { + "required": [ + "variables" + ] + }, + { + "required": [ + "target" + ] + } + ], + "errorMessage": "property.binding ${0/type} requires variables or target" + } + }, + { + "if": { + "properties": { + "type": { + "const": "camunda:out" + } + }, + "required": [ + "type" + ] + }, + "then": { + "oneOf": [ + { + "required": [ + "variables" + ] + }, + { + "required": [ + "source" + ] + }, + { + "required": [ + "sourceExpression" + ] + } + ], + "errorMessage": "property.binding ${0/type} requires variables, sourceExpression or source" + } + } + ], + "properties": { + "type": { + "$id": "#/properties/property/binding/type", + "type": "string", + "title": "property binding type", + "enum": [ + "property", + "camunda:property", + "camunda:inputParameter", + "camunda:outputParameter", + "camunda:in", + "camunda:out", + "camunda:in:businessKey", + "camunda:executionListener", + "camunda:field" + ], + "errorMessage": "invalid property.binding type ${0}; must be any of { property, camunda:property, camunda:inputParameter, camunda:outputParameter, camunda:in, camunda:out, camunda:in:businessKey, camunda:executionListener, camunda:field }", + "description": "The type of the property binding" + }, + "name": { + "$id": "#/properties/property/binding/name", + "type": "string", + "title": "property binding name", + "description": "The name of binding xml property" + }, + "event": { + "$id": "#/properties/property/binding/event", + "type": "string", + "title": "property binding event", + "description": "The event type of an execution listener binding" + }, + "scriptFormat": { + "$id": "#/properties/property/binding/scriptFormat", + "type": "string", + "title": "property binding script format", + "description": "The format of a script property binding (camunda:outputParameter, camunda:inputParameter)" + }, + "source": { + "$id": "#/properties/property/binding/source", + "type": "string", + "title": "property binding source", + "description": "The source value of a property binding (camunda:outputParameter, camunda:out)" + }, + "target": { + "$id": "#/properties/property/binding/target", + "type": "string", + "title": "property binding target", + "description": "The target value to be mapped to (camunda:in)" + }, + "expression": { + "$id": "#/properties/property/binding/expression", + "type": "boolean", + "title": "property binding expression", + "description": "True indicates that the control field value is an expression (camunda:in, camunda:field)" + }, + "variables": { + "$id": "#/properties/property/binding/variables", + "type": "string", + "title": "property binding variables", + "enum": [ + "all", + "local" + ], + "description": "Either all or local indicating the variable mapping (camunda:in)" + }, + "sourceExpression": { + "$id": "#/properties/property/binding/sourceExpression", + "type": "string", + "title": "property binding source expression", + "description": "The string containing the expression for the source attribute (camunda:out)" + } + } + }, + "constraints": { + "$id": "#/properties/property/constraints", + "type": "object", + "title": "property constraints", + "description": "The validation constraints", + "properties": { + "notEmpty": { + "$id": "#/properties/property/constraints/notEmpty", + "type": "boolean", + "title": "property constraints not empty", + "description": "The control field must not be empty" + }, + "minLength": { + "$id": "#/properties/property/constraints/minLength", + "type": "string", + "title": "property constraints min length", + "description": "The minimal length for the control field value" + }, + "maxLength": { + "$id": "#/properties/property/constraints/maxLength", + "type": "string", + "title": "property constraints max length", + "description": "The maximal length for the control field value" + }, + "pattern": { + "$id": "#/properties/property/constraints/pattern", + "type": "object", + "title": "property constraints pattern", + "description": "A regular expression pattern for the constraints", + "properties": { + "value": { + "$id": "#/properties/property/constraints/pattern/value", + "type": "string", + "title": "property constraints pattern value", + "description": "The regular expression of the pattern constraint" + }, + "message": { + "$id": "#/properties/property/constraints/pattern/message", + "type": "string", + "title": "property constraints pattern message", + "description": "The validation message of the pattern constraint" + } + } + } + } + } + } + } + }, + "metadata": { + "$id": "#/metadata", + "type": "object", + "title": "element template metadata", + "description": "Some metadata for further configuration" + }, + "scopes": { + "$id": "#/scopes", + "type": "object", + "title": "element template scope", + "description": "Special scoped bindings that allow you to configure nested elements" + }, + "entriesVisible": { + "$id": "#/entriesVisible", + "deprecated": true, + "type": "object", + "title": "element template entries visible", + "description": "@Deprecated - Select which entries are visible in the properties panel" + } + } +} \ No newline at end of file diff --git a/documentation/pom.xml b/documentation/pom.xml new file mode 100644 index 0000000..af7ecae --- /dev/null +++ b/documentation/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + + dev.bpm-crafters.process-engine-worker + process-engine-worker-root + 0.6.1-SNAPSHOT + + + process-engine-worker-documentation + ${artifactId} + + documentation-api + documentation-core + documentation-plugin + + pom + + diff --git a/examples/camunda7-documentation-example/README.md b/examples/camunda7-documentation-example/README.md new file mode 100644 index 0000000..254aae8 --- /dev/null +++ b/examples/camunda7-documentation-example/README.md @@ -0,0 +1,7 @@ +# camunda7-documentation-example + +camunda7-documentation-example is a minimal example to demonstrate the generation of documentation (element-templates) for process-engine-workers. + +## Usage + +Build the project with `mvn clean install` and checkout the generated documentation (element-templates) in [src/main/resources/bpmn/](src/main/resources/bpmn). diff --git a/examples/camunda7-documentation-example/pom.xml b/examples/camunda7-documentation-example/pom.xml new file mode 100644 index 0000000..cb6d290 --- /dev/null +++ b/examples/camunda7-documentation-example/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + dev.bpm-crafters.process-engine-worker + process-engine-worker-examples + 0.6.1-SNAPSHOT + + + camunda7-documentation-example + + + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-core + ${project.version} + + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-api + ${project.version} + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + + + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-maven-plugin + 0.6.1-SNAPSHOT + + C7 + ATTRIBUTE_NAME + true + src/main/resources/bpmn/element-templates + + + + + + + + + + generate + + process-classes + + + + + + diff --git a/examples/camunda7-documentation-example/src/main/kotlin/worker/ExampleDto.kt b/examples/camunda7-documentation-example/src/main/kotlin/worker/ExampleDto.kt new file mode 100644 index 0000000..fc96cb9 --- /dev/null +++ b/examples/camunda7-documentation-example/src/main/kotlin/worker/ExampleDto.kt @@ -0,0 +1,9 @@ +package worker + +import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerPropertyDocumentation + +data class ExampleDto( + @field:ProcessEngineWorkerPropertyDocumentation(label = "Example Input") + val exampleInput: String +) { +} diff --git a/examples/camunda7-documentation-example/src/main/kotlin/worker/ExampleWorker.kt b/examples/camunda7-documentation-example/src/main/kotlin/worker/ExampleWorker.kt new file mode 100644 index 0000000..13d40c5 --- /dev/null +++ b/examples/camunda7-documentation-example/src/main/kotlin/worker/ExampleWorker.kt @@ -0,0 +1,14 @@ +package worker + +import dev.bpmcrafters.processengine.worker.ProcessEngineWorker +import dev.bpmcrafters.processengine.worker.Variable +import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerDocumentation + +class ExampleWorker { + + @ProcessEngineWorker("example-worker") + @ProcessEngineWorkerDocumentation(name = "Example Worker", description = "Example worker for documentation generation") + fun execute(@Variable(name = "exampleDto") exampleDto: ExampleDto): ExampleDto { + return exampleDto + } +} diff --git a/examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json b/examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json new file mode 100644 index 0000000..00d3a0f --- /dev/null +++ b/examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json @@ -0,0 +1,67 @@ +{ + "$schema" : "https://unpkg.com/@camunda/element-templates-json-schema@0.1.0/resources/schema.json", + "name" : "Example Worker", + "id" : "example-worker", + "appliesTo" : [ "bpmn:ServiceTask" ], + "properties" : [ { + "value" : "external", + "label" : "Implementation Type", + "type" : "String", + "editable" : false, + "binding" : { + "type" : "property", + "name" : "camunda:type" + } + }, { + "value" : "example-worker", + "label" : "Topic", + "type" : "String", + "editable" : false, + "binding" : { + "type" : "property", + "name" : "camunda:topic" + } + }, { + "value" : false, + "label" : "Async Before", + "type" : "Boolean", + "editable" : true, + "binding" : { + "type" : "property", + "name" : "camunda:asyncBefore" + } + }, { + "value" : false, + "label" : "Async After", + "type" : "Boolean", + "editable" : true, + "binding" : { + "type" : "property", + "name" : "camunda:asyncAfter" + } + }, { + "value" : "${exampleInput}", + "label" : "Input: Example Input", + "type" : "String", + "editable" : true, + "binding" : { + "type" : "camunda:inputParameter", + "name" : "exampleInput" + }, + "constraints" : { + "notEmpty" : false + } + }, { + "value" : "exampleInput", + "label" : "Output: Example Input", + "type" : "String", + "editable" : true, + "binding" : { + "type" : "camunda:outputParameter", + "source" : "${exampleInput}" + }, + "constraints" : { + "notEmpty" : false + } + } ] +} \ No newline at end of file diff --git a/examples/pom.xml b/examples/pom.xml index 6005b74..b2c236b 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -24,6 +24,7 @@ order-fulfillment camunda7-remote-starter-native camunda7-embedded-starter-transaction + camunda7-documentation-example diff --git a/pom.xml b/pom.xml index 90e8639..e42c0f0 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,7 @@ spring-boot-starter + documentation From 8455251c7fecb09c098ae9651e0d3389c9b30304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6sle?= Date: Mon, 1 Sep 2025 16:06:32 +0200 Subject: [PATCH 2/9] feature: add engine-specific configs and refactor maven plugin structure --- docs/process-engine-worker.md | 64 ++++++++++ .../worker/documentation/core/C7Config.kt | 6 + .../core/DocumentationFailedException.kt | 4 + .../core/EngineSpecificConfig.kt | 5 + .../core/WorkerDocumentationGenerator.kt | 111 ++++++++++++++++++ .../core/generator/DocumentationGenerator.kt | 62 ---------- .../generator/EngineDocumentationGenerator.kt | 3 +- .../c7/Camunda7ElementTemplateGenerator.kt | 17 ++- .../WorkerDocumentationGeneratorMojo.kt | 75 ++++-------- .../camunda7-documentation-example/pom.xml | 10 +- .../element-templates/Example-Worker.json | 2 +- 11 files changed, 230 insertions(+), 129 deletions(-) create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/C7Config.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/DocumentationFailedException.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/EngineSpecificConfig.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGenerator.kt delete mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/DocumentationGenerator.kt diff --git a/docs/process-engine-worker.md b/docs/process-engine-worker.md index 3148e7c..c7db2f2 100644 --- a/docs/process-engine-worker.md +++ b/docs/process-engine-worker.md @@ -75,8 +75,72 @@ If the annotation `@org.springframework.transaction.annotation.Transactional` wi is used, the library will execute the worker method and the completion of the external task via API in the same transaction. This will lead to a transaction rollback, if the external task can't be completed (e.g. due to a network error). +## Documentation +You can automatically document your workers with the `process-engine-worker-documentation-api` and create on each build with the `process-engine-worker-documentation-maven-plugin` maven plugin element templates for the workers. +1. Add the `process-engine-worker-documentation-api` +```xml + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-api + ${process-engine-worker.version} + +``` + +2. Add the `@ProcessEngineWorkerDocumentation` annotation to your worker + +```kotlin + @ProcessEngineWorker("example-worker") + @ProcessEngineWorkerDocumentation(name = "Example Worker", description = "Example worker for documentation generation") + fun execute(@Variable(name = "exampleDto") exampleDto: ExampleDto): ExampleDto { + return exampleDto + } +``` +3. Add the `@ProcessEngineWorkerPropertyDocumentation` annotation to your in and output variables +```kotlin +data class ExampleDto( + @field:ProcessEngineWorkerPropertyDocumentation(label = "Example Input") + val exampleInput: String +) { +} +``` + +```java +public record ExampleDto( + @ProcessEngineWorkerPropertyDocumentation(label = "Example Input") + private String exampleInput +){} +``` + +4. Add the maven plugin to your `pom.xml`s plugin section + +```xml + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-maven-plugin + 0.6.1-SNAPSHOT + + C7 + ATTRIBUTE_NAME + true + src/main/resources/bpmn/element-templates + + + true + + + + + + + generate + + process-classes + + + +``` diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/C7Config.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/C7Config.kt new file mode 100644 index 0000000..9f55358 --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/C7Config.kt @@ -0,0 +1,6 @@ +package dev.bpmcrafters.processengine.worker.documentation.core + +data class C7Config( + val asyncBeforeDefaultValue: Boolean = false, + val asyncAfterDefaultValue: Boolean = false +) diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/DocumentationFailedException.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/DocumentationFailedException.kt new file mode 100644 index 0000000..1a635c8 --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/DocumentationFailedException.kt @@ -0,0 +1,4 @@ +package dev.bpmcrafters.processengine.worker.documentation.core + +class DocumentationFailedException(message: String, cause: Throwable?): RuntimeException(message, cause) { +} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/EngineSpecificConfig.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/EngineSpecificConfig.kt new file mode 100644 index 0000000..5139665 --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/EngineSpecificConfig.kt @@ -0,0 +1,5 @@ +package dev.bpmcrafters.processengine.worker.documentation.core + +data class EngineSpecificConfig( + val c7: C7Config = C7Config() +) diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGenerator.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGenerator.kt new file mode 100644 index 0000000..662e4d8 --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGenerator.kt @@ -0,0 +1,111 @@ +package dev.bpmcrafters.processengine.worker.documentation.core + +import dev.bpmcrafters.processengine.worker.ProcessEngineWorker +import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerDocumentation +import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerPropertyDocumentation +import dev.bpmcrafters.processengine.worker.documentation.core.generator.EngineDocumentationGenerator +import dev.bpmcrafters.processengine.worker.documentation.core.generator.ProcessEngineWorkerDocumentationInfo +import dev.bpmcrafters.processengine.worker.documentation.core.generator.ProcessEngineWorkerPropertyInfo +import dev.bpmcrafters.processengine.worker.documentation.core.generator.engines.c7.Camunda7ElementTemplateGenerator +import org.apache.commons.io.FileUtils +import org.apache.maven.project.MavenProject +import org.reflections.Reflections +import org.reflections.scanners.Scanners +import org.reflections.util.ClasspathHelper +import org.reflections.util.ConfigurationBuilder +import java.io.File +import java.io.IOException +import java.net.URL +import java.net.URLClassLoader + +class WorkerDocumentationGenerator( + val project: MavenProject, + val engine: TargetPlattform, + val outputDirectory: File, + val engineSpecificConfig: EngineSpecificConfig, + val inputValueNamingPolicy: InputValueNamingPolicy = InputValueNamingPolicy.EMPTY, +) { + + val engineDocumentationGenerators = listOf( + Camunda7ElementTemplateGenerator() + ) + + /** + * Clean the output directory + */ + fun clean() { + try { + FileUtils.deleteDirectory(outputDirectory) + } catch (e: IOException) { + throw DocumentationFailedException("Failed to clean output directory", e) + } + } + + /** + * Generates engine-specific documentation to the outputDirectory like e.g. c7 element templates + */ + fun generate() { + // Find annotated workers + val classpathURLs = project.compileClasspathElements + .map { File(it).toURI().toURL() } + val urlClassLoader = URLClassLoader(classpathURLs.toTypedArray(), javaClass.getClassLoader()) + val reflections = Reflections( + ConfigurationBuilder() + .setUrls(ClasspathHelper.forClassLoader(urlClassLoader)) + .addClassLoaders(urlClassLoader) + .addScanners(Scanners.MethodsAnnotated) + ) + val workers = reflections.getMethodsAnnotatedWith(ProcessEngineWorker::class.java) + + val engine = engineDocumentationGenerators + .filter { it.isSupported(engine) } + .let { if (it.size != 1) throw DocumentationFailedException("Expected exactly one engine documentation generator for $engine, but got ${it.size}", null) else it.first() } + + // generate documentation for each worker + workers.forEach { + if (it.parameterTypes.size > 1) { + throw DocumentationFailedException("Worker method ${it.name} has more than one parameter.", null) + } + + val inputParam = it.parameterTypes.first() + val returnType = it.returnType + + try { + val workerAnnotation = it.getAnnotation(ProcessEngineWorker::class.java) + val documentationAnnotation = it.getAnnotation(ProcessEngineWorkerDocumentation::class.java) + + val processEngineWorkerDocumentation = ProcessEngineWorkerDocumentationInfo( + documentationAnnotation.name, + documentationAnnotation.description, + documentationAnnotation.version, + workerAnnotation.topic, + generateProperties(inputParam), + generateProperties(returnType) + ) + + val result = engine.generate(processEngineWorkerDocumentation, inputValueNamingPolicy, engineSpecificConfig) + + FileUtils.createParentDirectories(outputDirectory) + val workerDocumentation = File(outputDirectory, result.fileName) + FileUtils.write(workerDocumentation, result.content, "UTF-8") + } catch (e: NullPointerException) { + throw DocumentationFailedException("Worker method ${it.name} is missing @ProcessEngineWorkerDocumentation annotation.", e) + } + } + } + + private fun generateProperties(type: Class<*>): List { + return type.declaredFields.map { field -> + val annotation = field.getAnnotation(ProcessEngineWorkerPropertyDocumentation::class.java) + ProcessEngineWorkerPropertyInfo( + name = field.name, + label = annotation.label, + type = annotation.type, + editable = annotation.editable, + notEmpty = annotation.notEmpty, + ) + } + } + + +} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/DocumentationGenerator.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/DocumentationGenerator.kt deleted file mode 100644 index 9faa1cb..0000000 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/DocumentationGenerator.kt +++ /dev/null @@ -1,62 +0,0 @@ -package dev.bpmcrafters.processengine.worker.documentation.core.generator - -import dev.bpmcrafters.processengine.worker.ProcessEngineWorker -import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerDocumentation -import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerPropertyDocumentation -import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy -import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform -import dev.bpmcrafters.processengine.worker.documentation.core.generator.engines.c7.Camunda7ElementTemplateGenerator -import org.apache.commons.io.FileUtils -import java.io.File - -class DocumentationGenerator( - val outputPath: File, - val engine: TargetPlattform, - val namingPolicy: InputValueNamingPolicy = InputValueNamingPolicy.EMPTY -) { - - val engineDocumentationGenerators = listOf( - Camunda7ElementTemplateGenerator() - ) - - fun generate( - workerAnnotation: ProcessEngineWorker, - documentationAnnotation: ProcessEngineWorkerDocumentation, - parameter: Class<*>, - returnType: Class<*> - ) { - val processEngineWorkerDocumentation = ProcessEngineWorkerDocumentationInfo( - documentationAnnotation.name, - documentationAnnotation.description, - documentationAnnotation.version, - workerAnnotation.topic, - generateProperties(parameter), - generateProperties(returnType) - ) - - val engine = engineDocumentationGenerators - .filter { it.isSupported(engine) } - .let { if (it.size != 1) throw RuntimeException("Expected exactly one engine documentation generator for $engine, but got ${it.size}") else it.first() } - - val result = engine.generate(processEngineWorkerDocumentation, namingPolicy) - - FileUtils.createParentDirectories(outputPath) - - val workerDocumentation = File(outputPath, result.fileName) - FileUtils.write(workerDocumentation, result.content, "UTF-8") - } - - private fun generateProperties(type: Class<*>): List { - return type.declaredFields.map { field -> - val annotation = field.getAnnotation(ProcessEngineWorkerPropertyDocumentation::class.java) - ProcessEngineWorkerPropertyInfo( - name = field.name, - label = annotation.label, - type = annotation.type, - editable = annotation.editable, - notEmpty = annotation.notEmpty, - ) - } - } - -} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt index 753ebc7..bb811ed 100644 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt @@ -1,11 +1,12 @@ package dev.bpmcrafters.processengine.worker.documentation.core.generator +import dev.bpmcrafters.processengine.worker.documentation.core.EngineSpecificConfig import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform interface EngineDocumentationGenerator { - fun generate(processEngineWorkerDocumentationInfo: ProcessEngineWorkerDocumentationInfo, namingPolicy: InputValueNamingPolicy): GenerationResult + fun generate(processEngineWorkerDocumentationInfo: ProcessEngineWorkerDocumentationInfo, namingPolicy: InputValueNamingPolicy, engineSpecificConfig: EngineSpecificConfig): GenerationResult fun isSupported(targetPlattform: TargetPlattform): Boolean diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt index 155641f..90b9849 100644 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt @@ -8,12 +8,13 @@ import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.ge import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen.CamundaC7ElementTemplate import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen.Constraints import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen.Property +import dev.bpmcrafters.processengine.worker.documentation.core.EngineSpecificConfig import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform import dev.bpmcrafters.processengine.worker.documentation.core.generator.* class Camunda7ElementTemplateGenerator: EngineDocumentationGenerator { - override fun generate(processEngineWorkerDocumentationInfo: ProcessEngineWorkerDocumentationInfo, namingPolicy: InputValueNamingPolicy): GenerationResult { + override fun generate(processEngineWorkerDocumentationInfo: ProcessEngineWorkerDocumentationInfo, namingPolicy: InputValueNamingPolicy, engineSpecificConfig: EngineSpecificConfig): GenerationResult { val elementTemplate = CamundaC7ElementTemplate() .withName(processEngineWorkerDocumentationInfo.name) .withId(processEngineWorkerDocumentationInfo.type) @@ -35,12 +36,12 @@ class Camunda7ElementTemplateGenerator: EngineDocumentationGenerator { // Add asyncBefore property - val asyncBeforeProperty = createAsyncBeforeProperty() + val asyncBeforeProperty = createAsyncBeforeProperty(engineSpecificConfig.c7.asyncBeforeDefaultValue) elementTemplate.properties.add(asyncBeforeProperty) // Add asyncAfter property - val asyncAfterProperty = createAsyncAfterProperty() + val asyncAfterProperty = createAsyncAfterProperty(engineSpecificConfig.c7.asyncAfterDefaultValue) elementTemplate.properties.add(asyncAfterProperty) @@ -144,12 +145,11 @@ class Camunda7ElementTemplateGenerator: EngineDocumentationGenerator { ) } - // TODO async before should be configurable - private fun createAsyncBeforeProperty(): Property { + private fun createAsyncBeforeProperty(asyncBefore: Boolean): Property { return Property() .withLabel("Async Before") .withType("Boolean") - .withValue(false) + .withValue(asyncBefore) .withEditable(true) .withChoices(null) .withBinding( @@ -159,12 +159,11 @@ class Camunda7ElementTemplateGenerator: EngineDocumentationGenerator { ) } - // TODO async before should be configurable - private fun createAsyncAfterProperty(): Property { + private fun createAsyncAfterProperty(asyncAfter: Boolean): Property { return Property() .withLabel("Async After") .withType("Boolean") - .withValue(false) + .withValue(asyncAfter) .withEditable(true) .withChoices(null) .withBinding( diff --git a/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt b/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt index 0f25058..ad9fd3a 100644 --- a/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt +++ b/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt @@ -1,11 +1,6 @@ package dev.bpmcrafters.processengine.worker.documentation -import dev.bpmcrafters.processengine.worker.ProcessEngineWorker -import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerDocumentation -import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy -import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform -import dev.bpmcrafters.processengine.worker.documentation.core.generator.DocumentationGenerator -import org.apache.commons.io.FileUtils +import dev.bpmcrafters.processengine.worker.documentation.core.* import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.logging.Log @@ -14,14 +9,7 @@ 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 org.reflections.Reflections -import org.reflections.scanners.Scanners -import org.reflections.util.ClasspathHelper -import org.reflections.util.ConfigurationBuilder import java.io.File -import java.io.IOException -import java.net.URL -import java.net.URLClassLoader @Mojo(name = "generate", defaultPhase = LifecyclePhase.PROCESS_CLASSES, requiresDependencyResolution = ResolutionScope.RUNTIME) class WorkerDocumentationGeneratorMojo: AbstractMojo() { @@ -57,51 +45,36 @@ class WorkerDocumentationGeneratorMojo: AbstractMojo() { @Parameter(name = "clean", property = "elementtemplategen.clean", defaultValue = "false") var clean: Boolean = false + /** + * Platform-specific configuration options + */ + @Parameter + var platformSpecificConfig: EngineSpecificConfig = EngineSpecificConfig() + override fun execute() { log.info("Generating element templates for ${project?.artifactId}") - // Clean output directory - if (clean) { - try { - log.info("Cleaning output directory...") - FileUtils.deleteDirectory(outputDirectory) - } catch(e: IOException) { - log.error("Failed to clean output directory.", e) - throw MojoExecutionException("Failed to clean output directory.", e) - } - } - - // Find annotated workers - val classpathURLs = project!!.compileClasspathElements - .map { File(it).toURI().toURL() } - val urlClassLoader = URLClassLoader(classpathURLs.toTypedArray(), javaClass.getClassLoader()) - val reflections = Reflections( - ConfigurationBuilder() - .setUrls(ClasspathHelper.forClassLoader(urlClassLoader)) - .addClassLoaders(urlClassLoader) - .addScanners(Scanners.MethodsAnnotated) + val workerDocumentationGenerator = WorkerDocumentationGenerator( + requireNotNull(project), + requireNotNull(targetPlatform), + requireNotNull(outputDirectory), + platformSpecificConfig, + requireNotNull(inputValueNamingPolicy) ) - val workers = reflections.getMethodsAnnotatedWith(ProcessEngineWorker::class.java) - val generator = DocumentationGenerator(outputDirectory!!, targetPlatform!!, inputValueNamingPolicy!!) - - // generate documentation for each worker - workers.forEach({ - val inputParams = it.parameterTypes - if (inputParams.size > 1) { - throw MojoExecutionException("Worker method ${it.name} has more than one parameter.") + try { + if (clean) { + log.info("Cleaning output directory...") + workerDocumentationGenerator.clean() } + log.info("Generate worker documentation") + workerDocumentationGenerator.generate() + } catch (e: DocumentationFailedException) { + log.error(e.message) + log.debug(e) + throw MojoExecutionException(e.message) + } - try { - val workerAnnotation = it.getAnnotation(ProcessEngineWorker::class.java) - val documentationAnnotation = it.getAnnotation(ProcessEngineWorkerDocumentation::class.java) - - generator.generate(workerAnnotation, documentationAnnotation, inputParams.first(), it.returnType) - } catch(e: NullPointerException) { - log.error("Worker method ${it.name} is missing required annotation.", e) - throw MojoExecutionException("Worker method ${it.name} is missing @ProcessEngineWorkerDocumentation annotation.") - } - }) } } diff --git a/examples/camunda7-documentation-example/pom.xml b/examples/camunda7-documentation-example/pom.xml index cb6d290..f88c84b 100644 --- a/examples/camunda7-documentation-example/pom.xml +++ b/examples/camunda7-documentation-example/pom.xml @@ -40,11 +40,11 @@ ATTRIBUTE_NAME true src/main/resources/bpmn/element-templates - - - - - + + + true + + diff --git a/examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json b/examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json index 00d3a0f..a01338f 100644 --- a/examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json +++ b/examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json @@ -31,7 +31,7 @@ "name" : "camunda:asyncBefore" } }, { - "value" : false, + "value" : true, "label" : "Async After", "type" : "Boolean", "editable" : true, From 911132bf04e38da7ffdb17bba02cd6b6e614ccb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6sle?= Date: Mon, 1 Sep 2025 17:36:46 +0200 Subject: [PATCH 3/9] test: add junit tests for documentation maven plugin --- .../c7/Camunda7ElementTemplateGenerator.kt | 2 +- .../core/WorkerDocumentationGeneratorTest.kt | 89 +++++++++++++++++++ .../Camunda7ElementTemplateGeneratorTest.kt | 71 +++++++++++++++ .../WorkerDocumentationGeneratorMojo.kt | 6 +- .../WorkerDocumentationGeneratorMojoTest.kt | 78 ++++++++++++++++ 5 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGeneratorTest.kt create mode 100644 documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGeneratorTest.kt create mode 100644 documentation/documentation-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt index 90b9849..fffc3fd 100644 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt @@ -21,7 +21,7 @@ class Camunda7ElementTemplateGenerator: EngineDocumentationGenerator { .withAppliesTo(mutableListOf(BPMNElementType.BPMN_SERVICE_TASK.value)) if (processEngineWorkerDocumentationInfo.version > 0) { - elementTemplate.version = processEngineWorkerDocumentationInfo.version as Double + elementTemplate.version = processEngineWorkerDocumentationInfo.version.toDouble() } diff --git a/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGeneratorTest.kt b/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGeneratorTest.kt new file mode 100644 index 0000000..bf255e6 --- /dev/null +++ b/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGeneratorTest.kt @@ -0,0 +1,89 @@ +package dev.bpmcrafters.processengine.worker.documentation.core + +import dev.bpmcrafters.processengine.worker.ProcessEngineWorker +import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerDocumentation +import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerPropertyDocumentation +import org.apache.maven.project.MavenProject +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import java.io.File + +class WorkerDocumentationGeneratorTest { + + // Test helper types that will be discovered by Reflections + data class InDto( + @field:ProcessEngineWorkerPropertyDocumentation(label = "In Label") + val inField: String + ) + data class OutDto( + @field:ProcessEngineWorkerPropertyDocumentation(label = "Out Label") + val outField: String + ) + class TestWorkerClass { + @ProcessEngineWorker(topic = "testTopic") + @ProcessEngineWorkerDocumentation(name = "Test Worker", description = "desc", version = 1) + fun work(input: InDto): OutDto = OutDto("x") + } + + @TempDir + lateinit var tempDir: File + + @Test + fun `generate creates element template file for annotated worker`() { + val testClassesPath = File(this::class.java.protectionDomain.codeSource.location.toURI()).path + + val project = mock { + on { compileClasspathElements } doReturn(listOf(testClassesPath)) + } + + val generator = WorkerDocumentationGenerator( + project = project, + engine = TargetPlattform.C7, + outputDirectory = tempDir, + engineSpecificConfig = EngineSpecificConfig(), + inputValueNamingPolicy = InputValueNamingPolicy.EMPTY + ) + + // when + generator.generate() + + // then + val expectedFile = File(tempDir, "Test-Worker.json") + assertThat(expectedFile).exists() + val content = expectedFile.readText() + assertThat(content) + .contains("\"name\" : \"Test Worker\"") + .contains("\"id\" : \"testTopic\"") + .contains("Input: In Label") + .contains("Output: Out Label") + } + + @Test + fun `clean deletes output directory`() { + val project = mock { + on { compileClasspathElements } doReturn(emptyList()) + } + + // create a file inside + val testFile = File(tempDir, "some.txt").writeText("data") + assertThat(tempDir) + .exists() + assertThat(testFile) + + val generator = WorkerDocumentationGenerator( + project = project, + engine = TargetPlattform.C7, + outputDirectory = tempDir, + engineSpecificConfig = EngineSpecificConfig(), + inputValueNamingPolicy = InputValueNamingPolicy.EMPTY + ) + + generator.clean() + + assertThat(tempDir.exists()) + .isFalse() + } +} diff --git a/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGeneratorTest.kt b/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGeneratorTest.kt new file mode 100644 index 0000000..238ea99 --- /dev/null +++ b/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGeneratorTest.kt @@ -0,0 +1,71 @@ +package dev.bpmcrafters.processengine.worker.documentation.core.generator.engines.c7 + +import dev.bpmcrafters.processengine.worker.documentation.api.PropertyType +import dev.bpmcrafters.processengine.worker.documentation.core.C7Config +import dev.bpmcrafters.processengine.worker.documentation.core.EngineSpecificConfig +import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy +import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform +import dev.bpmcrafters.processengine.worker.documentation.core.generator.ProcessEngineWorkerDocumentationInfo +import dev.bpmcrafters.processengine.worker.documentation.core.generator.ProcessEngineWorkerPropertyInfo +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +class Camunda7ElementTemplateGeneratorTest { + + private val generator = Camunda7ElementTemplateGenerator() + + @Test + fun `isSupported returns true only for C7`() { + assertThat(generator.isSupported(TargetPlattform.C7)).isTrue() + } + + @Test + fun `generate builds expected JSON and metadata`() { + val info = ProcessEngineWorkerDocumentationInfo( + name = "My Worker", + description = "desc", + version = -1, + type = "myTopic", + inputProperties = listOf( + ProcessEngineWorkerPropertyInfo( + name = "foo", + label = "Foo", + type = PropertyType.STRING, + editable = true, + notEmpty = false + ) + ), + outputProperties = listOf( + ProcessEngineWorkerPropertyInfo( + name = "bar", + label = "Bar", + type = PropertyType.STRING, + editable = true, + notEmpty = false + ) + ) + ) + + val config = EngineSpecificConfig(c7 = C7Config(asyncBeforeDefaultValue = true, asyncAfterDefaultValue = false)) + + val result = generator.generate(info, InputValueNamingPolicy.ATTRIBUTE_NAME, config) + + assertThat(result) + .hasFieldOrPropertyWithValue("name", info.name) + .hasFieldOrPropertyWithValue("fileName", "My-Worker.json") + .hasFieldOrPropertyWithValue("engine", TargetPlattform.C7) + assertThat(result.content) + .contains("\"\$schema\"") + .contains("\"name\" : \"My Worker\"") + .contains("\"id\" : \"myTopic\"") + .contains("\"camunda:type\"") + .contains("\"external\"") + .contains("\"camunda:topic\"") + .contains("\"myTopic\"") + .contains("Input: Foo") + .contains("Output: Bar") + .contains("Async Before") + .contains("Async After") + } + +} diff --git a/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt b/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt index ad9fd3a..0a5d66f 100644 --- a/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt +++ b/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt @@ -51,10 +51,14 @@ class WorkerDocumentationGeneratorMojo: AbstractMojo() { @Parameter var platformSpecificConfig: EngineSpecificConfig = EngineSpecificConfig() + // Minimal factory hook for testing/injection + var generatorFactory: (MavenProject, TargetPlattform, File, EngineSpecificConfig, InputValueNamingPolicy) -> WorkerDocumentationGenerator = + { project, target, outputDir, cfg, naming -> WorkerDocumentationGenerator(project, target, outputDir, cfg, naming) } + override fun execute() { log.info("Generating element templates for ${project?.artifactId}") - val workerDocumentationGenerator = WorkerDocumentationGenerator( + val workerDocumentationGenerator = generatorFactory( requireNotNull(project), requireNotNull(targetPlatform), requireNotNull(outputDirectory), diff --git a/documentation/documentation-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt b/documentation/documentation-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt new file mode 100644 index 0000000..3da2f36 --- /dev/null +++ b/documentation/documentation-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt @@ -0,0 +1,78 @@ +package dev.bpmcrafters.processengine.worker.documentation + +import dev.bpmcrafters.processengine.worker.documentation.core.EngineSpecificConfig +import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy +import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform +import dev.bpmcrafters.processengine.worker.documentation.core.WorkerDocumentationGenerator +import org.apache.maven.plugin.MojoExecutionException +import org.apache.maven.project.MavenProject +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.Test +import org.mockito.kotlin.doThrow +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.verify +import java.io.File + +class WorkerDocumentationGeneratorMojoTest { + + @Test + fun `execute with clean true calls clean and generate`() { + val mojo = WorkerDocumentationGeneratorMojo().apply { + project = mock() + targetPlatform = TargetPlattform.C7 + outputDirectory = mock() + inputValueNamingPolicy = InputValueNamingPolicy.EMPTY + platformSpecificConfig = EngineSpecificConfig() + clean = true + } + + val mockGenerator = mock() + mojo.generatorFactory = { _, _, _, _, _ -> mockGenerator } + + mojo.execute() + + verify(mockGenerator).clean() + verify(mockGenerator).generate() + } + + @Test + fun `execute with clean false calls only generate`() { + val mojo = WorkerDocumentationGeneratorMojo().apply { + project = mock() + targetPlatform = TargetPlattform.C7 + outputDirectory = mock() + inputValueNamingPolicy = InputValueNamingPolicy.EMPTY + platformSpecificConfig = EngineSpecificConfig() + clean = false + } + + val mockGenerator = mock() + mojo.generatorFactory = { _, _, _, _, _ -> mockGenerator } + + mojo.execute() + + verify(mockGenerator, never()).clean() + verify(mockGenerator).generate() + } + + @Test + fun `execute wraps DocumentationFailedException into MojoExecutionException`() { + val mojo = WorkerDocumentationGeneratorMojo().apply { + project = mock() + targetPlatform = TargetPlattform.C7 + outputDirectory = mock() + inputValueNamingPolicy = InputValueNamingPolicy.EMPTY + platformSpecificConfig = EngineSpecificConfig() + clean = false + } + + val failingGenerator = mock { + on { generate() } doThrow dev.bpmcrafters.processengine.worker.documentation.core.DocumentationFailedException("boom", null) + } + mojo.generatorFactory = { _, _, _, _, _ -> failingGenerator } + + assertThatThrownBy { mojo.execute() } + .isInstanceOf(MojoExecutionException::class.java) + } +} From 8ecc459c6e6db5478efbf207f11548e0a90b8e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6sle?= Date: Mon, 1 Sep 2025 17:43:12 +0200 Subject: [PATCH 4/9] feature: use maven clean install in ci pipeline --- .github/workflows/development.yml | 4 ++-- .github/workflows/master.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index cb9eb89..77dad32 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -43,11 +43,11 @@ jobs: # Build - name: Build with Maven - run: ./mvnw clean verify -U -B -ntp -T4 + run: ./mvnw clean install -U -B -ntp -T4 # itest - name: Run itest - run: ./mvnw integration-test failsafe:verify -Pitest -ntp -U -B -T4 + run: ./mvnw integration-test failsafe:install -Pitest -ntp -U -B -T4 # - name: Upload coverage to Codecov diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 8db1cb0..57a8df0 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -34,7 +34,7 @@ jobs: # Build - name: Build with Maven - run: ./mvnw clean verify -U -B -T4 + run: ./mvnw clean install -U -B -T4 # Get GPG private key into GPG - name: Import GPG Owner Trust From 33cb83a8f4854a561cfc01bf5bb5df1b028f9969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6sle?= Date: Mon, 1 Sep 2025 17:50:42 +0200 Subject: [PATCH 5/9] bugfix: fix maven parent --- documentation/documentation-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/documentation-plugin/pom.xml b/documentation/documentation-plugin/pom.xml index 09f6580..c2a88ca 100644 --- a/documentation/documentation-plugin/pom.xml +++ b/documentation/documentation-plugin/pom.xml @@ -5,7 +5,7 @@ 4.0.0 dev.bpm-crafters.process-engine-worker - process-engine-worker-root + process-engine-worker-documentation 0.6.1-SNAPSHOT From 67142be784decfa513f2cf19e79b6ae594be59d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6sle?= Date: Mon, 1 Sep 2025 17:54:06 +0200 Subject: [PATCH 6/9] bugfix: fix ci pipeline --- .github/workflows/development.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index 77dad32..f0dd18d 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -47,7 +47,7 @@ jobs: # itest - name: Run itest - run: ./mvnw integration-test failsafe:install -Pitest -ntp -U -B -T4 + run: ./mvnw integration-test failsafe:verify -Pitest -ntp -U -B -T4 # - name: Upload coverage to Codecov From f6ab8b301646e2833e3a06e5301a5f66d0810100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6sle?= Date: Tue, 2 Sep 2025 08:36:51 +0200 Subject: [PATCH 7/9] bugfix: fix ci pipeline --- .../camunda7/external/ExternalTaskCompletionAfterCommitTest.kt | 2 ++ .../camunda7/external/ExternalTaskCompletionBeforeCommitTest.kt | 2 ++ .../external/ExternalTaskCompletionWithoutTransactionTest.kt | 2 ++ 3 files changed, 6 insertions(+) diff --git a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionAfterCommitTest.kt b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionAfterCommitTest.kt index c1ddcba..f44f8e0 100644 --- a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionAfterCommitTest.kt +++ b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionAfterCommitTest.kt @@ -4,6 +4,7 @@ import org.assertj.core.api.Assertions.assertThat import org.awaitility.Awaitility.await import org.junit.jupiter.api.Test import org.springframework.context.annotation.Import +import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.TestPropertySource import java.util.* import java.util.concurrent.TimeUnit.SECONDS @@ -12,6 +13,7 @@ import java.util.concurrent.TimeUnit.SECONDS @TestPropertySource(properties = [ "dev.bpm-crafters.process-api.worker.complete-tasks-before-commit=false" ]) +@ActiveProfiles("itest") class ExternalTaskCompletionAfterCommitTest : AbstractTransactionalBehaviorTest() { @Test diff --git a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionBeforeCommitTest.kt b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionBeforeCommitTest.kt index f9fcf39..4a2f2f4 100644 --- a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionBeforeCommitTest.kt +++ b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionBeforeCommitTest.kt @@ -4,6 +4,7 @@ import org.assertj.core.api.Assertions.assertThat import org.awaitility.Awaitility.await import org.junit.jupiter.api.Test import org.springframework.context.annotation.Import +import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.TestPropertySource import java.util.* import java.util.concurrent.TimeUnit.SECONDS @@ -12,6 +13,7 @@ import java.util.concurrent.TimeUnit.SECONDS @TestPropertySource(properties = [ "dev.bpm-crafters.process-api.worker.complete-tasks-before-commit=true" ]) +@ActiveProfiles("itest") class ExternalTaskCompletionBeforeCommitTest : AbstractTransactionalBehaviorTest() { @Test diff --git a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionWithoutTransactionTest.kt b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionWithoutTransactionTest.kt index 3422c67..853965f 100644 --- a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionWithoutTransactionTest.kt +++ b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionWithoutTransactionTest.kt @@ -10,10 +10,12 @@ import org.awaitility.Awaitility.await import org.camunda.community.rest.client.api.ProcessInstanceApiClient import org.junit.jupiter.api.Test import org.springframework.context.annotation.Import +import org.springframework.test.context.ActiveProfiles import java.util.* import java.util.concurrent.TimeUnit.SECONDS @Import(ExternalTaskCompletionWithoutTransactionTest.WorkerWithoutTransactionalAnnotation::class) +@ActiveProfiles("itest") class ExternalTaskCompletionWithoutTransactionTest : AbstractTransactionalBehaviorTest() { class WorkerWithoutTransactionalAnnotation( From c48a7f4988c06ac5e742bd854254b940f516a5fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6sle?= Date: Tue, 2 Sep 2025 08:45:51 +0200 Subject: [PATCH 8/9] bugfix: fix ci pipeline --- .../camunda7/external/ExternalTaskCompletionAfterCommitTest.kt | 2 -- .../camunda7/external/ExternalTaskCompletionBeforeCommitTest.kt | 2 -- .../external/ExternalTaskCompletionWithoutTransactionTest.kt | 2 -- 3 files changed, 6 deletions(-) diff --git a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionAfterCommitTest.kt b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionAfterCommitTest.kt index f44f8e0..c1ddcba 100644 --- a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionAfterCommitTest.kt +++ b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionAfterCommitTest.kt @@ -4,7 +4,6 @@ import org.assertj.core.api.Assertions.assertThat import org.awaitility.Awaitility.await import org.junit.jupiter.api.Test import org.springframework.context.annotation.Import -import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.TestPropertySource import java.util.* import java.util.concurrent.TimeUnit.SECONDS @@ -13,7 +12,6 @@ import java.util.concurrent.TimeUnit.SECONDS @TestPropertySource(properties = [ "dev.bpm-crafters.process-api.worker.complete-tasks-before-commit=false" ]) -@ActiveProfiles("itest") class ExternalTaskCompletionAfterCommitTest : AbstractTransactionalBehaviorTest() { @Test diff --git a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionBeforeCommitTest.kt b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionBeforeCommitTest.kt index 4a2f2f4..f9fcf39 100644 --- a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionBeforeCommitTest.kt +++ b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionBeforeCommitTest.kt @@ -4,7 +4,6 @@ import org.assertj.core.api.Assertions.assertThat import org.awaitility.Awaitility.await import org.junit.jupiter.api.Test import org.springframework.context.annotation.Import -import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.TestPropertySource import java.util.* import java.util.concurrent.TimeUnit.SECONDS @@ -13,7 +12,6 @@ import java.util.concurrent.TimeUnit.SECONDS @TestPropertySource(properties = [ "dev.bpm-crafters.process-api.worker.complete-tasks-before-commit=true" ]) -@ActiveProfiles("itest") class ExternalTaskCompletionBeforeCommitTest : AbstractTransactionalBehaviorTest() { @Test diff --git a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionWithoutTransactionTest.kt b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionWithoutTransactionTest.kt index 853965f..3422c67 100644 --- a/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionWithoutTransactionTest.kt +++ b/spring-boot-starter/src/test/kotlin/dev/bpmcrafters/processengine/worker/itest/camunda7/external/ExternalTaskCompletionWithoutTransactionTest.kt @@ -10,12 +10,10 @@ import org.awaitility.Awaitility.await import org.camunda.community.rest.client.api.ProcessInstanceApiClient import org.junit.jupiter.api.Test import org.springframework.context.annotation.Import -import org.springframework.test.context.ActiveProfiles import java.util.* import java.util.concurrent.TimeUnit.SECONDS @Import(ExternalTaskCompletionWithoutTransactionTest.WorkerWithoutTransactionalAnnotation::class) -@ActiveProfiles("itest") class ExternalTaskCompletionWithoutTransactionTest : AbstractTransactionalBehaviorTest() { class WorkerWithoutTransactionalAnnotation( From 22b652a12cc3855b6b13e5a76266e8ecb5e5d180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6sle?= Date: Tue, 2 Sep 2025 17:01:36 +0200 Subject: [PATCH 9/9] feature: separate camunda7 and camunda8 generation plugins --- docs/process-engine-worker.md | 68 +- documentation/documentation-api/pom.xml | 2 +- .../documentation-c7-maven-plugin/pom.xml | 96 +++ .../worker/documentation}/C7Config.kt | 2 +- .../WorkerDocumentationGeneratorMojo.kt | 22 +- .../Camunda7ElementTemplateGenerator.kt | 69 +- .../schema/camunda-c7-element-template.json | 0 .../WorkerDocumentationGeneratorMojoTest.kt | 21 +- .../Camunda7ElementTemplateGeneratorTest.kt | 28 +- .../pom.xml | 4 +- .../WorkerDocumentationGeneratorMojo.kt | 65 ++ .../Camunda8ElementTemplateGenerator.kt | 105 +++ .../documentation/engine/schema/Binding.kt | 71 ++ .../engine/schema/CamundaC8ElementTemplate.kt | 96 +++ .../documentation/engine/schema/Choice.kt | 29 + .../documentation/engine/schema/Condition.kt | 3 + .../engine/schema/Constraints.kt | 41 + .../engine/schema/ElementType.kt | 24 + .../documentation/engine/schema/Equals.kt | 20 + .../documentation/engine/schema/Expression.kt | 3 + .../documentation/engine/schema/Group.kt | 29 + .../documentation/engine/schema/Icon.kt | 23 + .../documentation/engine/schema/Metadata.kt | 17 + .../engine/schema/MultipleConditions.kt | 21 + .../documentation/engine/schema/OneOf.kt | 20 + .../documentation/engine/schema/Property.kt | 101 +++ .../engine/schema/SingleCondition.kt | 35 + .../schema/camunda-c8-element-template.json | 812 ++++++++++++++++++ .../WorkerDocumentationGeneratorMojoTest.kt | 67 ++ .../Camunda8ElementTemplateGeneratorTest.kt | 59 ++ documentation/documentation-core/pom.xml | 32 +- .../core/EngineSpecificConfig.kt | 5 - .../core/InputValueNamingPolicy.kt | 6 - .../documentation/core/SchemaJsonConverter.kt | 26 + .../{generator/engines/c7 => }/SchemaMixin.kt | 2 +- .../documentation/core/TargetPlattform.kt | 5 - .../core/WorkerDocumentationGenerator.kt | 22 +- .../generator/EngineDocumentationGenerator.kt | 13 - .../core/generator/GenerationResult.kt | 11 - .../core/WorkerDocumentationGeneratorTest.kt | 38 +- .../schema/camunda-c7-element-template.json | 540 ------------ documentation/generator-api/pom.xml | 23 + .../generator/api}/BPMNElementType.kt | 2 +- .../api}/DocumentationFailedException.kt | 2 +- .../api/EngineDocumentationGeneratorApi.kt | 7 + .../generator/api/GenerationResult.kt | 9 + .../generator/api/InputValueNamingPolicy.kt | 6 + .../ProcessEngineWorkerDocumentationInfo.kt | 2 +- .../api}/ProcessEngineWorkerPropertyInfo.kt | 2 +- .../generator/api/TargetPlattform.kt | 6 + documentation/pom.xml | 6 +- .../camunda7-documentation-example/pom.xml | 12 +- .../element-templates/Example-Worker.json | 2 +- 53 files changed, 1963 insertions(+), 769 deletions(-) create mode 100644 documentation/documentation-c7-maven-plugin/pom.xml rename documentation/{documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core => documentation-c7-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation}/C7Config.kt (64%) rename documentation/{documentation-plugin => documentation-c7-maven-plugin}/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt (74%) rename documentation/{documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7 => documentation-c7-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine}/Camunda7ElementTemplateGenerator.kt (62%) rename documentation/{documentation-core => documentation-c7-maven-plugin}/src/main/resources/schema/camunda-c7-element-template.json (100%) rename documentation/{documentation-plugin => documentation-c7-maven-plugin}/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt (62%) rename documentation/{documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7 => documentation-c7-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine}/Camunda7ElementTemplateGeneratorTest.kt (59%) rename documentation/{documentation-plugin => documentation-c8-maven-plugin}/pom.xml (93%) create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda8ElementTemplateGenerator.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Binding.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/CamundaC8ElementTemplate.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Choice.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Condition.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Constraints.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/ElementType.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Equals.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Expression.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Group.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Icon.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Metadata.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/MultipleConditions.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/OneOf.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Property.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/SingleCondition.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/main/resources/schema/camunda-c8-element-template.json create mode 100644 documentation/documentation-c8-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt create mode 100644 documentation/documentation-c8-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda8ElementTemplateGeneratorTest.kt delete mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/EngineSpecificConfig.kt delete mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/InputValueNamingPolicy.kt create mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/SchemaJsonConverter.kt rename documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/{generator/engines/c7 => }/SchemaMixin.kt (77%) delete mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/TargetPlattform.kt delete mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt delete mode 100644 documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/GenerationResult.kt delete mode 100644 documentation/documentation-plugin/src/main/resources/schema/camunda-c7-element-template.json create mode 100644 documentation/generator-api/pom.xml rename documentation/{documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator => generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api}/BPMNElementType.kt (71%) rename documentation/{documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core => generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api}/DocumentationFailedException.kt (60%) create mode 100644 documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/EngineDocumentationGeneratorApi.kt create mode 100644 documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/GenerationResult.kt create mode 100644 documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/InputValueNamingPolicy.kt rename documentation/{documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator => generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api}/ProcessEngineWorkerDocumentationInfo.kt (78%) rename documentation/{documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator => generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api}/ProcessEngineWorkerPropertyInfo.kt (76%) create mode 100644 documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/TargetPlattform.kt diff --git a/docs/process-engine-worker.md b/docs/process-engine-worker.md index c7db2f2..8367e04 100644 --- a/docs/process-engine-worker.md +++ b/docs/process-engine-worker.md @@ -118,29 +118,49 @@ public record ExampleDto( 4. Add the maven plugin to your `pom.xml`s plugin section +**C7 Maven Plugin** + +```xml + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-c7-maven-plugin + 0.6.1-SNAPSHOT + + true + src/main/resources/bpmn/element-templates + + true + + + + + + generate + + process-classes + + + +``` + +**C8 Maven Plugin** + ```xml - - dev.bpm-crafters.process-engine-worker - process-engine-worker-documentation-maven-plugin - 0.6.1-SNAPSHOT - - C7 - ATTRIBUTE_NAME - true - src/main/resources/bpmn/element-templates - - - true - - - - - - - generate - - process-classes - - - + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-c8-maven-plugin + 0.6.1-SNAPSHOT + + true + src/main/resources/bpmn/element-templates + + + + + generate + + process-classes + + + ``` diff --git a/documentation/documentation-api/pom.xml b/documentation/documentation-api/pom.xml index ef8954c..53c3d9e 100644 --- a/documentation/documentation-api/pom.xml +++ b/documentation/documentation-api/pom.xml @@ -10,6 +10,6 @@ process-engine-worker-documentation-api - ${artifactId} + ${project.artifactId} diff --git a/documentation/documentation-c7-maven-plugin/pom.xml b/documentation/documentation-c7-maven-plugin/pom.xml new file mode 100644 index 0000000..b7fd0f4 --- /dev/null +++ b/documentation/documentation-c7-maven-plugin/pom.xml @@ -0,0 +1,96 @@ + + + 4.0.0 + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation + 0.6.1-SNAPSHOT + + + process-engine-worker-documentation-c7-maven-plugin + ${project.artifactId} + maven-plugin + Maven plugin to generate camunda 7 element templates + + + 3.9.11 + 3.15.1 + 0.10.2 + 3.15.1 + + + + + + org.apache.maven + maven-plugin-api + ${org.apache.maven.version} + + + + org.apache.maven + maven-core + ${org.apache.maven.version} + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${org.apache.maven.plugin-tools.version} + provided + + + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-core + ${project.version} + + + + + + + org.apache.maven.plugins + maven-plugin-plugin + ${org.apache.maven-plugins.version} + + + + + + + + + org.apache.maven.plugins + maven-plugin-plugin + ${org.apache.maven-plugins.version} + + + + + + + org.jsonschema2pojo + jsonschema2pojo-maven-plugin + 1.2.2 + + ${basedir}/src/main/resources/schema + dev.bpmcrafters.processengine.worker.documentation.elementtemplates.gen + true + true + + + + generate-sources + + generate + + + + + + + + diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/C7Config.kt b/documentation/documentation-c7-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/C7Config.kt similarity index 64% rename from documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/C7Config.kt rename to documentation/documentation-c7-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/C7Config.kt index 9f55358..539f245 100644 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/C7Config.kt +++ b/documentation/documentation-c7-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/C7Config.kt @@ -1,4 +1,4 @@ -package dev.bpmcrafters.processengine.worker.documentation.core +package dev.bpmcrafters.processengine.worker.documentation data class C7Config( val asyncBeforeDefaultValue: Boolean = false, diff --git a/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt b/documentation/documentation-c7-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt similarity index 74% rename from documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt rename to documentation/documentation-c7-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt index 0a5d66f..76b6a75 100644 --- a/documentation/documentation-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt +++ b/documentation/documentation-c7-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt @@ -1,6 +1,10 @@ package dev.bpmcrafters.processengine.worker.documentation -import dev.bpmcrafters.processengine.worker.documentation.core.* +import dev.bpmcrafters.processengine.worker.documentation.core.WorkerDocumentationGenerator +import dev.bpmcrafters.processengine.worker.documentation.engine.Camunda7ElementTemplateGenerator +import dev.bpmcrafters.processengine.worker.documentation.generator.api.DocumentationFailedException +import dev.bpmcrafters.processengine.worker.documentation.generator.api.EngineDocumentationGeneratorApi +import dev.bpmcrafters.processengine.worker.documentation.generator.api.InputValueNamingPolicy import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.logging.Log @@ -19,12 +23,6 @@ class WorkerDocumentationGeneratorMojo: AbstractMojo() { @Parameter(defaultValue = "\${project}", required = true, readonly = true) var project: MavenProject? = null - /** - * The target platform for which goal should be executed. - */ - @Parameter(name = "targetPlatform", property = "elementtemplategen.targetPlatform", required = true) - var targetPlatform: TargetPlattform? = null - /** * Directory to output the generated element templates to. */ @@ -49,21 +47,19 @@ class WorkerDocumentationGeneratorMojo: AbstractMojo() { * Platform-specific configuration options */ @Parameter - var platformSpecificConfig: EngineSpecificConfig = EngineSpecificConfig() + var c7Config: C7Config = C7Config() // Minimal factory hook for testing/injection - var generatorFactory: (MavenProject, TargetPlattform, File, EngineSpecificConfig, InputValueNamingPolicy) -> WorkerDocumentationGenerator = - { project, target, outputDir, cfg, naming -> WorkerDocumentationGenerator(project, target, outputDir, cfg, naming) } + var generatorFactory: (MavenProject, File, EngineDocumentationGeneratorApi) -> WorkerDocumentationGenerator = + { project, outputDir, generator -> WorkerDocumentationGenerator(project, outputDir, generator) } override fun execute() { log.info("Generating element templates for ${project?.artifactId}") val workerDocumentationGenerator = generatorFactory( requireNotNull(project), - requireNotNull(targetPlatform), requireNotNull(outputDirectory), - platformSpecificConfig, - requireNotNull(inputValueNamingPolicy) + Camunda7ElementTemplateGenerator(c7Config = c7Config) ) try { diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt b/documentation/documentation-c7-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda7ElementTemplateGenerator.kt similarity index 62% rename from documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt rename to documentation/documentation-c7-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda7ElementTemplateGenerator.kt index fffc3fd..3d823a6 100644 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGenerator.kt +++ b/documentation/documentation-c7-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda7ElementTemplateGenerator.kt @@ -1,20 +1,20 @@ -package dev.bpmcrafters.processengine.worker.documentation.core.generator.engines.c7 +package dev.bpmcrafters.processengine.worker.documentation.engine -import com.fasterxml.jackson.core.JsonProcessingException -import com.fasterxml.jackson.databind.MapperFeature -import com.fasterxml.jackson.databind.json.JsonMapper +import dev.bpmcrafters.processengine.worker.documentation.C7Config import dev.bpmcrafters.processengine.worker.documentation.api.PropertyType -import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen.Binding -import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen.CamundaC7ElementTemplate -import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen.Constraints -import dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen.Property -import dev.bpmcrafters.processengine.worker.documentation.core.EngineSpecificConfig -import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy -import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform -import dev.bpmcrafters.processengine.worker.documentation.core.generator.* - -class Camunda7ElementTemplateGenerator: EngineDocumentationGenerator { - override fun generate(processEngineWorkerDocumentationInfo: ProcessEngineWorkerDocumentationInfo, namingPolicy: InputValueNamingPolicy, engineSpecificConfig: EngineSpecificConfig): GenerationResult { +import dev.bpmcrafters.processengine.worker.documentation.core.SchemaJsonConverter +import dev.bpmcrafters.processengine.worker.documentation.elementtemplates.gen.Binding +import dev.bpmcrafters.processengine.worker.documentation.elementtemplates.gen.CamundaC7ElementTemplate +import dev.bpmcrafters.processengine.worker.documentation.elementtemplates.gen.Constraints +import dev.bpmcrafters.processengine.worker.documentation.elementtemplates.gen.Property +import dev.bpmcrafters.processengine.worker.documentation.generator.api.* + +class Camunda7ElementTemplateGenerator( + private val inputValueNamingPolicy: InputValueNamingPolicy = InputValueNamingPolicy.EMPTY, + private val c7Config: C7Config = C7Config() +): EngineDocumentationGeneratorApi { + + override fun generate(processEngineWorkerDocumentationInfo: ProcessEngineWorkerDocumentationInfo): GenerationResult { val elementTemplate = CamundaC7ElementTemplate() .withName(processEngineWorkerDocumentationInfo.name) .withId(processEngineWorkerDocumentationInfo.type) @@ -36,18 +36,18 @@ class Camunda7ElementTemplateGenerator: EngineDocumentationGenerator { // Add asyncBefore property - val asyncBeforeProperty = createAsyncBeforeProperty(engineSpecificConfig.c7.asyncBeforeDefaultValue) + val asyncBeforeProperty = createAsyncBeforeProperty(c7Config.asyncBeforeDefaultValue) elementTemplate.properties.add(asyncBeforeProperty) // Add asyncAfter property - val asyncAfterProperty = createAsyncAfterProperty(engineSpecificConfig.c7.asyncAfterDefaultValue) + val asyncAfterProperty = createAsyncAfterProperty(c7Config.asyncAfterDefaultValue) elementTemplate.properties.add(asyncAfterProperty) // Add properties for input parameters for (inputProperty in processEngineWorkerDocumentationInfo.inputProperties) { - val property = createInputParameterProp(inputProperty, namingPolicy) + val property = createInputParameterProp(inputProperty, inputValueNamingPolicy) elementTemplate.properties.add(property) } @@ -58,20 +58,18 @@ class Camunda7ElementTemplateGenerator: EngineDocumentationGenerator { elementTemplate.properties.add(property) } - val json = toJsonString(elementTemplate) + val jsonSchema = "https://unpkg.com/@camunda/element-templates-json-schema@0.1.0/resources/schema.json" + val json = SchemaJsonConverter.toJsonString(jsonSchema, elementTemplate, CamundaC7ElementTemplate::class.java) + return GenerationResult( - name = processEngineWorkerDocumentationInfo.name, - version = processEngineWorkerDocumentationInfo.version, - content = json, - fileName = processEngineWorkerDocumentationInfo.name.replace(" ", "-") + ".json", - engine = TargetPlattform.C7 + name = processEngineWorkerDocumentationInfo.name, + version = processEngineWorkerDocumentationInfo.version, + content = json, + fileName = processEngineWorkerDocumentationInfo.name.replace(" ", "-") + ".json", + engine = TargetPlattform.C7 ) } - override fun isSupported(targetPlattform: TargetPlattform): Boolean { - return TargetPlattform.C7 == targetPlattform - } - private fun createInputParameterProp( info: ProcessEngineWorkerPropertyInfo, inputValueNamingPolicy: InputValueNamingPolicy @@ -173,19 +171,4 @@ class Camunda7ElementTemplateGenerator: EngineDocumentationGenerator { ) } - private fun toJsonString(elementTemplate: CamundaC7ElementTemplate): String { - try { - val jsonSchema = "https://unpkg.com/@camunda/element-templates-json-schema@0.1.0/resources/schema.json" - val mapper = JsonMapper.builder() - .configure(MapperFeature.SORT_CREATOR_PROPERTIES_FIRST, true) - .addMixIn(CamundaC7ElementTemplate::class.java, SchemaMixin::class.java) - .build() - val objectWriter = mapper.writerFor(CamundaC7ElementTemplate::class.java) - .withAttribute("\$schema", jsonSchema) - return objectWriter.withDefaultPrettyPrinter().writeValueAsString(elementTemplate) - } catch (e: JsonProcessingException) { - throw RuntimeException("Could not generate json string!", e) - } - } - } diff --git a/documentation/documentation-core/src/main/resources/schema/camunda-c7-element-template.json b/documentation/documentation-c7-maven-plugin/src/main/resources/schema/camunda-c7-element-template.json similarity index 100% rename from documentation/documentation-core/src/main/resources/schema/camunda-c7-element-template.json rename to documentation/documentation-c7-maven-plugin/src/main/resources/schema/camunda-c7-element-template.json diff --git a/documentation/documentation-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt b/documentation/documentation-c7-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt similarity index 62% rename from documentation/documentation-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt rename to documentation/documentation-c7-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt index 3da2f36..da1607a 100644 --- a/documentation/documentation-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt +++ b/documentation/documentation-c7-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt @@ -1,9 +1,7 @@ package dev.bpmcrafters.processengine.worker.documentation -import dev.bpmcrafters.processengine.worker.documentation.core.EngineSpecificConfig -import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy -import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform import dev.bpmcrafters.processengine.worker.documentation.core.WorkerDocumentationGenerator +import dev.bpmcrafters.processengine.worker.documentation.generator.api.DocumentationFailedException import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.project.MavenProject import org.assertj.core.api.Assertions.assertThatThrownBy @@ -20,15 +18,12 @@ class WorkerDocumentationGeneratorMojoTest { fun `execute with clean true calls clean and generate`() { val mojo = WorkerDocumentationGeneratorMojo().apply { project = mock() - targetPlatform = TargetPlattform.C7 outputDirectory = mock() - inputValueNamingPolicy = InputValueNamingPolicy.EMPTY - platformSpecificConfig = EngineSpecificConfig() clean = true } val mockGenerator = mock() - mojo.generatorFactory = { _, _, _, _, _ -> mockGenerator } + mojo.generatorFactory = { _, _, _ -> mockGenerator } mojo.execute() @@ -40,15 +35,12 @@ class WorkerDocumentationGeneratorMojoTest { fun `execute with clean false calls only generate`() { val mojo = WorkerDocumentationGeneratorMojo().apply { project = mock() - targetPlatform = TargetPlattform.C7 outputDirectory = mock() - inputValueNamingPolicy = InputValueNamingPolicy.EMPTY - platformSpecificConfig = EngineSpecificConfig() clean = false } val mockGenerator = mock() - mojo.generatorFactory = { _, _, _, _, _ -> mockGenerator } + mojo.generatorFactory = { _, _, _ -> mockGenerator } mojo.execute() @@ -60,17 +52,14 @@ class WorkerDocumentationGeneratorMojoTest { fun `execute wraps DocumentationFailedException into MojoExecutionException`() { val mojo = WorkerDocumentationGeneratorMojo().apply { project = mock() - targetPlatform = TargetPlattform.C7 outputDirectory = mock() - inputValueNamingPolicy = InputValueNamingPolicy.EMPTY - platformSpecificConfig = EngineSpecificConfig() clean = false } val failingGenerator = mock { - on { generate() } doThrow dev.bpmcrafters.processengine.worker.documentation.core.DocumentationFailedException("boom", null) + on { generate() } doThrow DocumentationFailedException("boom", null) } - mojo.generatorFactory = { _, _, _, _, _ -> failingGenerator } + mojo.generatorFactory = { _, _, _ -> failingGenerator } assertThatThrownBy { mojo.execute() } .isInstanceOf(MojoExecutionException::class.java) diff --git a/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGeneratorTest.kt b/documentation/documentation-c7-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda7ElementTemplateGeneratorTest.kt similarity index 59% rename from documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGeneratorTest.kt rename to documentation/documentation-c7-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda7ElementTemplateGeneratorTest.kt index 238ea99..21adff2 100644 --- a/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/Camunda7ElementTemplateGeneratorTest.kt +++ b/documentation/documentation-c7-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda7ElementTemplateGeneratorTest.kt @@ -1,26 +1,22 @@ -package dev.bpmcrafters.processengine.worker.documentation.core.generator.engines.c7 +package dev.bpmcrafters.processengine.worker.documentation.engine +import dev.bpmcrafters.processengine.worker.documentation.C7Config import dev.bpmcrafters.processengine.worker.documentation.api.PropertyType -import dev.bpmcrafters.processengine.worker.documentation.core.C7Config -import dev.bpmcrafters.processengine.worker.documentation.core.EngineSpecificConfig -import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy -import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform -import dev.bpmcrafters.processengine.worker.documentation.core.generator.ProcessEngineWorkerDocumentationInfo -import dev.bpmcrafters.processengine.worker.documentation.core.generator.ProcessEngineWorkerPropertyInfo +import dev.bpmcrafters.processengine.worker.documentation.generator.api.InputValueNamingPolicy +import dev.bpmcrafters.processengine.worker.documentation.generator.api.ProcessEngineWorkerDocumentationInfo +import dev.bpmcrafters.processengine.worker.documentation.generator.api.ProcessEngineWorkerPropertyInfo +import dev.bpmcrafters.processengine.worker.documentation.generator.api.TargetPlattform import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test class Camunda7ElementTemplateGeneratorTest { - private val generator = Camunda7ElementTemplateGenerator() - - @Test - fun `isSupported returns true only for C7`() { - assertThat(generator.isSupported(TargetPlattform.C7)).isTrue() - } - @Test fun `generate builds expected JSON and metadata`() { + val config = C7Config(asyncBeforeDefaultValue = true, asyncAfterDefaultValue = false) + + val generator = Camunda7ElementTemplateGenerator(c7Config = config, inputValueNamingPolicy = InputValueNamingPolicy.ATTRIBUTE_NAME) + val info = ProcessEngineWorkerDocumentationInfo( name = "My Worker", description = "desc", @@ -46,9 +42,7 @@ class Camunda7ElementTemplateGeneratorTest { ) ) - val config = EngineSpecificConfig(c7 = C7Config(asyncBeforeDefaultValue = true, asyncAfterDefaultValue = false)) - - val result = generator.generate(info, InputValueNamingPolicy.ATTRIBUTE_NAME, config) + val result = generator.generate(info) assertThat(result) .hasFieldOrPropertyWithValue("name", info.name) diff --git a/documentation/documentation-plugin/pom.xml b/documentation/documentation-c8-maven-plugin/pom.xml similarity index 93% rename from documentation/documentation-plugin/pom.xml rename to documentation/documentation-c8-maven-plugin/pom.xml index c2a88ca..eda439c 100644 --- a/documentation/documentation-plugin/pom.xml +++ b/documentation/documentation-c8-maven-plugin/pom.xml @@ -9,10 +9,10 @@ 0.6.1-SNAPSHOT - process-engine-worker-documentation-maven-plugin + process-engine-worker-documentation-c8-maven-plugin ${project.artifactId} maven-plugin - Maven plugin to generate element templates + Maven plugin to generate camunda 8 element templates 3.9.11 diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt new file mode 100644 index 0000000..de39dca --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojo.kt @@ -0,0 +1,65 @@ +package dev.bpmcrafters.processengine.worker.documentation + +import dev.bpmcrafters.processengine.worker.documentation.core.WorkerDocumentationGenerator +import dev.bpmcrafters.processengine.worker.documentation.engine.Camunda8ElementTemplateGenerator +import dev.bpmcrafters.processengine.worker.documentation.generator.api.DocumentationFailedException +import dev.bpmcrafters.processengine.worker.documentation.generator.api.EngineDocumentationGeneratorApi +import org.apache.maven.plugin.AbstractMojo +import org.apache.maven.plugin.MojoExecutionException +import org.apache.maven.plugin.logging.Log +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 = "generate", defaultPhase = LifecyclePhase.PROCESS_CLASSES, requiresDependencyResolution = ResolutionScope.RUNTIME) +class WorkerDocumentationGeneratorMojo: AbstractMojo() { + + private val log: Log = getLog() + + @Parameter(defaultValue = "\${project}", required = true, readonly = true) + var project: MavenProject? = null + + /** + * Directory to output the generated element templates to. + */ + @Parameter(property = "elementtemplategen.outputDirectory", defaultValue = "\${project.build.directory/generated-sources/element-templates}") + var outputDirectory: File? = null + + /** + * A flag indicating if the output directory should be cleaned before generation. + */ + @Parameter(name = "clean", property = "elementtemplategen.clean", defaultValue = "false") + var clean: Boolean = false + + // Minimal factory hook for testing/injection + var generatorFactory: (MavenProject, File, EngineDocumentationGeneratorApi) -> WorkerDocumentationGenerator = + { project, outputDir, generator -> WorkerDocumentationGenerator(project, outputDir, generator) } + + override fun execute() { + log.info("Generating element templates for ${project?.artifactId}") + + val workerDocumentationGenerator = generatorFactory( + requireNotNull(project), + requireNotNull(outputDirectory), + Camunda8ElementTemplateGenerator() + ) + + try { + if (clean) { + log.info("Cleaning output directory...") + workerDocumentationGenerator.clean() + } + log.info("Generate worker documentation") + workerDocumentationGenerator.generate() + } catch (e: DocumentationFailedException) { + log.error(e.message) + log.debug(e) + throw MojoExecutionException(e.message) + } + + } + +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda8ElementTemplateGenerator.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda8ElementTemplateGenerator.kt new file mode 100644 index 0000000..bf85eeb --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda8ElementTemplateGenerator.kt @@ -0,0 +1,105 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine + +import dev.bpmcrafters.processengine.worker.documentation.api.PropertyType +import dev.bpmcrafters.processengine.worker.documentation.core.SchemaJsonConverter +import dev.bpmcrafters.processengine.worker.documentation.engine.schema.Binding +import dev.bpmcrafters.processengine.worker.documentation.engine.schema.CamundaC8ElementTemplate +import dev.bpmcrafters.processengine.worker.documentation.engine.schema.Constraints +import dev.bpmcrafters.processengine.worker.documentation.engine.schema.Property +import dev.bpmcrafters.processengine.worker.documentation.generator.api.* + +class Camunda8ElementTemplateGenerator( + private val inputValueNamingPolicy: InputValueNamingPolicy = InputValueNamingPolicy.EMPTY, +): EngineDocumentationGeneratorApi { + + override fun generate( + processEngineWorkerDocumentationInfo: ProcessEngineWorkerDocumentationInfo, + ): GenerationResult { + + val elementTemplate = CamundaC8ElementTemplate() + elementTemplate.name = processEngineWorkerDocumentationInfo.name + elementTemplate.id = processEngineWorkerDocumentationInfo.type + elementTemplate.appliesTo = mutableListOf(BPMNElementType.BPMN_SERVICE_TASK.value) + + + if (processEngineWorkerDocumentationInfo.version > 0) { + elementTemplate.version = processEngineWorkerDocumentationInfo.version + } + + val implementationTopicProperty = Property() + implementationTopicProperty.label = "Topic" + implementationTopicProperty.type = PropertyType.STRING.type + implementationTopicProperty.editable = false + val binding = Binding() + binding.type = Binding.Type.ZEEBE_TASKDEFINITION_TYPE + implementationTopicProperty.binding = binding + + elementTemplate.properties.add(implementationTopicProperty) + + for (inputProperty in processEngineWorkerDocumentationInfo.inputProperties) { + val property = createInputParameterProp(inputProperty, inputValueNamingPolicy) + elementTemplate.properties.add(property) + } + + for (ouputProperty in processEngineWorkerDocumentationInfo.outputProperties) { + val property = createOutputParameterProp(ouputProperty, inputValueNamingPolicy) + elementTemplate.properties.add(property) + } + + val jsonSchema = "https://unpkg.com/@camunda/element-templates-json-schema@0.1.0/resources/schema.json" + val json = SchemaJsonConverter.toJsonString(jsonSchema, elementTemplate, CamundaC8ElementTemplate::class.java) + + return GenerationResult( + name = processEngineWorkerDocumentationInfo.name, + version = processEngineWorkerDocumentationInfo.version, + content = json, + fileName = processEngineWorkerDocumentationInfo.name.replace(" ", "-") + ".json", + engine = TargetPlattform.C8 + ) + } + + private fun createInputParameterProp( + info: ProcessEngineWorkerPropertyInfo, + inputValueNamingPolicy: InputValueNamingPolicy + ): Property { + val property = Property() + property.label = "Input: " + info.label + property.value = if (InputValueNamingPolicy.ATTRIBUTE_NAME == inputValueNamingPolicy) "=" + info.name else "=" + property.type = info.type.type + val binding = Binding() + binding.type = Binding.Type.ZEEBE_INPUT + binding.name = info.name + property.binding = binding + + val constraint = Constraints() + constraint.notEmpty = info.notEmpty + property.constraints = constraint + + property.editable = info.editable + + return property + } + + private fun createOutputParameterProp( + info: ProcessEngineWorkerPropertyInfo, + inputValueNamingPolicy: InputValueNamingPolicy + ): Property { + val property = Property() + property.label = "Output: " + info.label + property.value = info.name + property.type = info.type.type + val binding = Binding() + binding.type = Binding.Type.ZEEBE_OUTPUT + binding.source = "=" + info.name + property.binding = binding + + val constraint = Constraints() + constraint.notEmpty = info.notEmpty + property.constraints = constraint + + property.editable = info.editable + + return property + } + +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Binding.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Binding.kt new file mode 100644 index 0000000..988c818 --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Binding.kt @@ -0,0 +1,71 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.fasterxml.jackson.annotation.JsonPropertyOrder +import com.fasterxml.jackson.annotation.JsonValue + +/** + * property binding + * Specifying how the property is mapped to BPMN or Zeebe extension elements and attributes + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "type", + "name", + "source", + "key" + ] +) +class Binding { + /** + * The type of a property binding (Required) + */ + @JsonProperty("type") + @JsonPropertyDescription("The type of a property binding") + var type: Type? = null + + /** + * The name of a property binding + */ + @JsonProperty("name") + @JsonPropertyDescription("The name of a property binding") + var name: String? = null + + /** + * The source value of a property binding (zeebe:output) + */ + @JsonProperty("source") + @JsonPropertyDescription("The source value of a property binding (zeebe:output)") + var source: String? = null + + /** + * The key value of a property binding (zeebe:taskHeader) + */ + @JsonProperty("key") + @JsonPropertyDescription("The key value of a property binding (zeebe:taskHeader)") + var key: String? = null + + /** + * property binding type + */ + enum class Type(@get:JsonValue val value: String) { + PROPERTY("property"), + ZEEBE_TASKDEFINITION_TYPE("zeebe:taskDefinition:type"), + ZEEBE_TASKDEFINITION_RETRIES("zeebe:taskDefinition:retries"), + ZEEBE_INPUT("zeebe:input"), + ZEEBE_OUTPUT("zeebe:output"), + ZEEBE_PROPERTY("zeebe:property"), + ZEEBE_TASKHEADER("zeebe:taskHeader"); + + companion object { + @JvmStatic + @JsonCreator + fun fromValue(value: String): Type = values().find { it.value == value } + ?: throw IllegalArgumentException(value) + } + } +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/CamundaC8ElementTemplate.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/CamundaC8ElementTemplate.kt new file mode 100644 index 0000000..3dd532d --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/CamundaC8ElementTemplate.kt @@ -0,0 +1,96 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.fasterxml.jackson.annotation.JsonPropertyOrder + +/** + * Element Template Schema + * An element template configuration + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "name", + "id", + "description", + "version", + "isDefault", + "appliesTo", + "elementType", + "metadata", + "entriesVisible", + "groups", + "documentationRef", + "properties", + "icon" + ] +) +class CamundaC8ElementTemplate { + /** The name of the element template (Required) */ + @JsonProperty("name") + @JsonPropertyDescription("The name of the element template") + var name: String? = null + + /** The identifier of the element template (Required) */ + @JsonProperty("id") + @JsonPropertyDescription("The identifier of the element template") + var id: String? = null + + /** The description of the element template */ + @JsonProperty("description") + @JsonPropertyDescription("The description of the element template") + var description: String? = null + + /** Optional version of the template. Unique by id+version */ + @JsonProperty("version") + @JsonPropertyDescription( + "Optional version of the template. If you add a version to a template it will be considered unique based on its ID and version. Two templates can have the same ID if their version is different" + ) + var version: Int? = null + + /** Indicates whether the element template is a default template */ + @JsonProperty("isDefault") + @JsonPropertyDescription("Indicates whether the element template is a default template") + var isDefault: Boolean? = null + + /** List of BPMN types the template can be applied to (Required) */ + @JsonProperty("appliesTo") + @JsonPropertyDescription("List of BPMN types the template can be applied to") + var appliesTo: MutableList = ArrayList() + + /** The BPMN type the element will be transformed into */ + @JsonProperty("elementType") + @JsonPropertyDescription("The BPMN type the element will be transformed into") + var elementType: ElementType? = null + + /** Some custom properties for further configuration */ + @JsonProperty("metadata") + @JsonPropertyDescription("Some custom properties for further configuration") + var metadata: Metadata? = null + + /** Select whether non-template entries are visible in the properties panel */ + @JsonProperty("entriesVisible") + @JsonPropertyDescription("Select whether non-template entries are visible in the properties panel") + var entriesVisible: Boolean? = null + + /** Custom fields can be ordered together via groups */ + @JsonProperty("groups") + @JsonPropertyDescription("Custom fields can be ordered together via groups") + var groups: MutableList = ArrayList() + + /** element template documentationRef */ + @JsonProperty("documentationRef") + var documentationRef: String? = null + + /** List of properties of the element template (Required) */ + @JsonProperty("properties") + @JsonPropertyDescription("List of properties of the element template") + var properties: MutableList = ArrayList() + + /** Custom icon to be shown on the element */ + @JsonProperty("icon") + @JsonPropertyDescription("Custom icon to be shown on the element") + var icon: Icon? = null +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Choice.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Choice.kt new file mode 100644 index 0000000..fb1f8fb --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Choice.kt @@ -0,0 +1,29 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.fasterxml.jackson.annotation.JsonPropertyOrder + +/** + * property choice + * The choices for dropdown fields + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "name", + "value" + ] +) +class Choice { + /** The name of a choice (Required) */ + @JsonProperty("name") + @JsonPropertyDescription("The name of a choice") + var name: String? = null + + /** The value of a choice (Required) */ + @JsonProperty("value") + @JsonPropertyDescription("The value of a choice") + var value: String? = null +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Condition.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Condition.kt new file mode 100644 index 0000000..0dc9181 --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Condition.kt @@ -0,0 +1,3 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +interface Condition diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Constraints.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Constraints.kt new file mode 100644 index 0000000..3b28f21 --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Constraints.kt @@ -0,0 +1,41 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.fasterxml.jackson.annotation.JsonPropertyOrder + +/** + * property constraints + * The validation constraints of a control field + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "notEmpty", + "minLength", + "maxLength", + "pattern" + ] +) +class Constraints { + /** The control field must not be empty */ + @JsonProperty("notEmpty") + @JsonPropertyDescription("The control field must not be empty") + var notEmpty: Boolean? = null + + /** The minimal length of a control field value */ + @JsonProperty("minLength") + @JsonPropertyDescription("The minimal length of a control field value") + var minLength: Double? = null + + /** The maximal length of a control field value */ + @JsonProperty("maxLength") + @JsonPropertyDescription("The maximal length of a control field value") + var maxLength: Double? = null + + /** A regular expression pattern for a constraint */ + @JsonProperty("pattern") + @JsonPropertyDescription("A regular expression pattern for a constraint") + var pattern: String? = null +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/ElementType.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/ElementType.kt new file mode 100644 index 0000000..d0a9454 --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/ElementType.kt @@ -0,0 +1,24 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyOrder + +/** + * element type + * The BPMN type the element will be transformed into + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "value" + ] +) +class ElementType { + /** + * element type value + * The identifier of the element template + */ + @JsonProperty("value") + var value: String? = null +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Equals.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Equals.kt new file mode 100644 index 0000000..210d01d --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Equals.kt @@ -0,0 +1,20 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyOrder + +/** + * condition equals + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "equals" + ] +) +class Equals : Expression { + /** condition equals */ + @JsonProperty("equals") + var equals: Any? = null +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Expression.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Expression.kt new file mode 100644 index 0000000..203d165 --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Expression.kt @@ -0,0 +1,3 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +interface Expression diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Group.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Group.kt new file mode 100644 index 0000000..4983390 --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Group.kt @@ -0,0 +1,29 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.fasterxml.jackson.annotation.JsonPropertyOrder + +/** + * element template groups + * Custom fields can be ordered together via groups + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "id", + "label" + ] +) +class Group { + /** The id of the custom group (Required) */ + @JsonProperty("id") + @JsonPropertyDescription("The id of the custom group") + var id: String? = null + + /** The label of the custom group (Required) */ + @JsonProperty("label") + @JsonPropertyDescription("The label of the custom group") + var label: String? = null +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Icon.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Icon.kt new file mode 100644 index 0000000..3efa185 --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Icon.kt @@ -0,0 +1,23 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.fasterxml.jackson.annotation.JsonPropertyOrder + +/** + * element template icon + * Custom icon to be shown on the element + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "contents" + ] +) +class Icon { + /** The URL of an icon (Required) */ + @JsonProperty("contents") + @JsonPropertyDescription("The URL of an icon") + var contents: String? = null +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Metadata.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Metadata.kt new file mode 100644 index 0000000..cca1120 --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Metadata.kt @@ -0,0 +1,17 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonIgnore +import com.fasterxml.jackson.annotation.JsonInclude +import java.util.LinkedHashMap + +/** + * element template metadata + * + * Some custom properties for further configuration + */ +@JsonInclude(JsonInclude.Include.NON_NULL) + +data class Metadata( + @field:JsonIgnore + var additionalProperties: MutableMap = LinkedHashMap() +) diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/MultipleConditions.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/MultipleConditions.kt new file mode 100644 index 0000000..07710a3 --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/MultipleConditions.kt @@ -0,0 +1,21 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyOrder + +/** + * property condition + * Condition(s) to activate the binding + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "allMatch" + ] +) +class MultipleConditions : Condition { + /** condition allMatch (Required) */ + @JsonProperty("allMatch") + var allMatch: MutableList = ArrayList() +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/OneOf.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/OneOf.kt new file mode 100644 index 0000000..ddd9dea --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/OneOf.kt @@ -0,0 +1,20 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyOrder + +/** + * condition oneOf + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "oneOf" + ] +) +class OneOf : Expression { + /** condition oneOf */ + @JsonProperty("oneOf") + var oneOf: MutableList = ArrayList() +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Property.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Property.kt new file mode 100644 index 0000000..d82627a --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/Property.kt @@ -0,0 +1,101 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.fasterxml.jackson.annotation.JsonPropertyOrder + +/** + * element template property + * List of properties of the element template + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "id", + "value", + "description", + "label", + "type", + "editable", + "choices", + "constraints", + "group", + "condition", + "binding", + "optional", + "feel", + "language" + ] +) +class Property { + /** Unique identifier of the property */ + @JsonProperty("id") + @JsonPropertyDescription("Unique identifier of the property") + var id: String? = null + + /** The value of a control field */ + @JsonProperty("value") + @JsonPropertyDescription("The value of a control field") + var value: Any? = null + + /** The description of a control field */ + @JsonProperty("description") + @JsonPropertyDescription("The description of a control field") + var description: String? = null + + /** The label of a control field */ + @JsonProperty("label") + @JsonPropertyDescription("The label of a control field") + var label: String? = null + + /** The type of a control field */ + @JsonProperty("type") + @JsonPropertyDescription("The type of a control field") + var type: String? = null + + /** Indicates whether a control field is editable or not */ + @JsonProperty("editable") + @JsonPropertyDescription("Indicates whether a control field is editable or not") + var editable: Boolean? = null + + /** The choices for dropdown fields */ + @JsonProperty("choices") + @JsonPropertyDescription("The choices for dropdown fields") + var choices: MutableList = ArrayList() + + /** The validation constraints of a control field */ + @JsonProperty("constraints") + @JsonPropertyDescription("The validation constraints of a control field") + var constraints: Constraints? = null + + /** The custom group of a control field */ + @JsonProperty("group") + @JsonPropertyDescription("The custom group of a control field") + var group: String? = null + + /** Condition(s) to activate the binding */ + @JsonProperty("condition") + @JsonPropertyDescription("Condition(s) to activate the binding") + var condition: Condition? = null + + /** Specifying how the property is mapped to BPMN or Zeebe extension elements and attributes (Required) */ + @JsonProperty("binding") + @JsonPropertyDescription("Specifying how the property is mapped to BPMN or Zeebe extension elements and attributes") + var binding: Binding? = null + + /** Indicates whether a property is optional. Optional bindings do not persist empty values in the underlying BPMN 2.0 XML */ + @JsonProperty("optional") + @JsonPropertyDescription("Indicates whether a property is optional. Optional bindings do not persist empty values in the underlying BPMN 2.0 XML") + var optional: Boolean? = null + + /** Indicates whether the property can be a feel expression */ + @JsonProperty("feel") + @JsonPropertyDescription("Indicates whether the property can be a feel expression") + var feel: String? = null + + /** Indicates that the field is a custom language editor */ + @JsonProperty("language") + @JsonPropertyDescription("Indicates that the field is a custom language editor") + var language: String? = null +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/SingleCondition.kt b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/SingleCondition.kt new file mode 100644 index 0000000..5626046 --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/schema/SingleCondition.kt @@ -0,0 +1,35 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine.schema + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonPropertyDescription +import com.fasterxml.jackson.annotation.JsonPropertyOrder +import com.fasterxml.jackson.annotation.JsonUnwrapped + +/** + * property condition + * Condition(s) to activate the binding + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder( + value = [ + "type", + "property", + "expression", + ] +) +class SingleCondition : Condition { + /** The type of the condition */ + @JsonProperty("type") + @JsonPropertyDescription("The type of the condition") + val type: String = "simple" + + /** The id of the property to check (Required) */ + @JsonProperty("property") + @JsonPropertyDescription("The id of the property to check") + var property: String? = null + + /** condition expression */ + @JsonUnwrapped + var expression: Expression? = null +} diff --git a/documentation/documentation-c8-maven-plugin/src/main/resources/schema/camunda-c8-element-template.json b/documentation/documentation-c8-maven-plugin/src/main/resources/schema/camunda-c8-element-template.json new file mode 100644 index 0000000..ab0c730 --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/main/resources/schema/camunda-c8-element-template.json @@ -0,0 +1,812 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://camunda.org/schema/zeebe-element-templates/1.0", + "title": "Element Template Schema", + "definitions": { + "properties": { + "allOf": [ + { + "type": "array", + "description": "List of properties of the element template.", + "allOf": [ + { + "examples": [ + [ + { + "label": "Name", + "type": "String", + "binding": { + "type": "property", + "name": "name" + } + } + ] + ] + } + ], + "items": { + "type": "object", + "default": {}, + "allOf": [ + { + "if": { + "properties": { + "type": { + "const": "Dropdown" + } + }, + "required": [ + "type" + ] + }, + "then": { + "required": [ + "choices" + ] + } + } + ], + "properties": { + "id": { + "type": "string", + "description": "Unique identifier of the property." + }, + "value": { + "$id": "#/properties/property/value", + "type": [ + "string", + "boolean" + ], + "description": "The value of a control field." + }, + "description": { + "$id": "#/properties/property/description", + "type": "string", + "description": "The description of a control field." + }, + "label": { + "$id": "#/properties/property/label", + "type": "string", + "description": "The label of a control field." + }, + "type": { + "$id": "#/properties/property/type", + "type": "string", + "description": "The type of a control field." + }, + "editable": { + "$id": "#/properties/property/editable", + "type": "boolean", + "description": "Indicates whether a control field is editable or not." + }, + "choices": { + "$id": "#/properties/property/choices", + "type": "array", + "description": "The choices for dropdown fields.", + "default": [], + "items": { + "$id": "#/properties/property/choices/item", + "type": "object", + "default": {}, + "properties": { + "name": { + "$id": "#/properties/property/choices/item/name", + "type": "string", + "description": "The name of a choice." + }, + "value": { + "$id": "#/properties/property/choices/item/value", + "type": "string", + "description": "The value of a choice." + } + }, + "required": [ + "value", + "name" + ] + } + }, + "constraints": { + "$id": "#/properties/property/constraints", + "type": "object", + "description": "The validation constraints of a control field.", + "allOf": [ + { + "examples": [ + { + "notEmpty": true + } + ] + } + ], + "properties": { + "notEmpty": { + "$id": "#/properties/property/constraints/notEmpty", + "type": "boolean", + "description": "The control field must not be empty." + }, + "minLength": { + "$id": "#/properties/property/constraints/minLength", + "type": "number", + "description": "The minimal length of a control field value." + }, + "maxLength": { + "$id": "#/properties/property/constraints/maxLength", + "type": "number", + "description": "The maximal length for a control field value." + }, + "pattern": { + "$id": "#/properties/property/constraints/pattern", + "description": "A regular expression pattern for a constraint.", + "oneOf": [ + { + "type": "object", + "default": {}, + "properties": { + "value": { + "$id": "#/properties/property/constraints/pattern/value", + "type": "string", + "description": "The regular expression of a pattern." + }, + "message": { + "$id": "#/properties/property/constraints/pattern/message", + "type": "string", + "description": "The validation message of a pattern." + } + } + }, + { + "type": "string" + } + ] + } + } + }, + "group": { + "$id": "#/properties/property/group", + "type": "string", + "description": "The custom group of a control field." + }, + "condition": { + "$id": "#/condition", + "type": "object", + "description": "Condition(s) to activate the binding.", + "allOf": [ + { + "examples": [ + { + "type": "simple", + "property": "httpMethod", + "equals": "GET" + }, + { + "type": "simple", + "property": "httpMethod", + "oneOf": [ + "POST", + "PUT", + "DELETE" + ] + }, + { + "allMatch": [ + { + "type": "simple", + "property": "authType", + "equals": "Basic" + }, + { + "type": "simple", + "property": "httpMethod", + "oneOf": [ + "POST", + "PUT", + "DELETE" + ] + } + ] + } + ] + } + ], + "definitions": { + "condition": { + "type": "object", + "required": [ + "property" + ], + "properties": { + "type": { + "$id": "#/condition/type", + "const": "simple", + "description": "The type of the condition.", + "default": "simple" + }, + "property": { + "$id": "#/condition/property", + "type": "string", + "description": "The id of the property to check." + } + }, + "oneOf": [ + { + "properties": { + "equals": { + "type": [ + "string", + "number", + "boolean" + ] + } + }, + "required": [ + "equals" + ] + }, + { + "properties": { + "oneOf": { + "type": "array", + "items": { + "type": [ + "string", + "number" + ] + } + } + }, + "required": [ + "oneOf" + ] + } + ] + } + }, + "oneOf": [ + { + "$ref": "#/definitions/properties/allOf/0/items/properties/condition/definitions/condition" + }, + { + "properties": { + "allMatch": { + "$id": "#/allMatch", + "type": "array", + "items": { + "$ref": "#/definitions/properties/allOf/0/items/properties/condition/definitions/condition" + }, + "minItems": 1 + } + }, + "required": [ + "allMatch" + ] + } + ] + } + } + } + }, + { + "$schema": "http://json-schema.org/draft-07/schema", + "type": "array", + "description": "List of properties of the element template.", + "items": { + "type": "object", + "default": {}, + "required": [ + "binding" + ], + "allOf": [ + { + "if": { + "properties": { + "binding": { + "properties": { + "type": { + "const": "property" + } + }, + "required": [ + "type" + ] + } + }, + "required": [ + "binding" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "String", + "Text", + "Hidden", + "Dropdown", + "Boolean" + ] + } + } + } + }, + { + "if": { + "properties": { + "binding": { + "properties": { + "type": { + "enum": [ + "zeebe:input", + "zeebe:output", + "zeebe:property", + "zeebe:taskHeader", + "zeebe:taskDefinition:retries", + "zeebe:taskDefinition:type" + ] + } + }, + "required": [ + "type" + ] + } + }, + "required": [ + "binding" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "String", + "Text", + "Hidden", + "Dropdown" + ] + } + } + } + }, + { + "if": { + "properties": { + "optional": { + "const": true + } + }, + "required": [ + "optional" + ] + }, + "then": { + "properties": { + "binding": { + "properties": { + "type": { + "enum": [ + "zeebe:input", + "zeebe:output", + "zeebe:property", + "zeebe:taskHeader" + ] + } + }, + "required": [ + "type" + ] + } + } + } + }, + { + "if": { + "properties": { + "optional": { + "const": true + } + }, + "required": [ + "optional" + ] + }, + "then": { + "properties": { + "constraints": { + "properties": { + "notEmpty": { + "const": false + } + }, + "required": [ + "notEmpty" + ] + } + } + } + }, + { + "if": { + "properties": { + "feel": { + "not": { + "const": null + } + } + }, + "required": [ + "feel" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "String", + "Text" + ] + } + }, + "required": [ + "type" + ] + } + }, + { + "if": { + "properties": { + "language": { + "not": { + "const": null + } + } + }, + "required": [ + "language" + ] + }, + "then": { + "properties": { + "type": { + "enum": [ + "Text" + ] + } + } + } + } + ], + "properties": { + "binding": { + "$id": "#/properties/property/binding", + "type": "object", + "description": "Specifying how the property is mapped to BPMN or Zeebe extension elements and attributes.", + "required": [ + "type" + ], + "allOf": [ + { + "if": { + "properties": { + "type": { + "enum": [ + "property", + "zeebe:property", + "zeebe:input" + ] + } + }, + "required": [ + "type" + ] + }, + "then": { + "required": [ + "name" + ] + } + }, + { + "if": { + "properties": { + "type": { + "const": "zeebe:output" + } + }, + "required": [ + "type" + ] + }, + "then": { + "required": [ + "source" + ] + } + }, + { + "if": { + "properties": { + "type": { + "const": "zeebe:taskHeader" + } + }, + "required": [ + "type" + ] + }, + "then": { + "required": [ + "key" + ] + } + }, + { + "examples": [ + { + "type": "property", + "name": "name" + }, + { + "type": "zeebe:input", + "name": "input" + }, + { + "type": "zeebe:output", + "source": "output" + }, + { + "type": "zeebe:property", + "name": "property" + }, + { + "type": "zeebe:taskDefinition:retries" + }, + { + "type": "zeebe:taskDefinition:type" + }, + { + "type": "zeebe:taskHeader", + "key": "key" + } + ] + } + ], + "properties": { + "type": { + "$id": "#/properties/property/binding/type", + "type": "string", + "description": "The type of a property binding.", + "enum": [ + "property", + "zeebe:taskDefinition:type", + "zeebe:taskDefinition:retries", + "zeebe:input", + "zeebe:output", + "zeebe:property", + "zeebe:taskHeader" + ] + }, + "name": { + "$id": "#/properties/property/binding/name", + "type": "string", + "description": "The name of a property binding." + }, + "source": { + "$id": "#/properties/property/binding/source", + "type": "string", + "description": "The source value of a property binding (zeebe:output)." + }, + "key": { + "$id": "#/properties/property/binding/key", + "type": "string", + "description": "The key value of a property binding (zeebe:taskHeader)." + } + } + }, + "optional": { + "$id": "#/optional", + "type": "boolean", + "description": "Indicates whether a property is optional. Optional bindings do not persist empty values in the underlying BPMN 2.0 XML." + }, + "feel": { + "$id": "#/properties/property/feel", + "type": "string", + "default": null, + "description": "Indicates whether the property can be a feel expression", + "enum": [ + null, + "optional", + "required" + ] + }, + "language": { + "$id": "#/properties/property/language", + "type": "string", + "description": "Indicates that the field is a custom language editor" + } + } + } + } + ] + }, + "template": { + "type": "object", + "allOf": [ + { + "required": [ + "name", + "id", + "appliesTo", + "properties" + ], + "properties": { + "name": { + "$id": "#/name", + "type": "string", + "description": "The name of the element template." + }, + "id": { + "$id": "#/id", + "type": "string", + "description": "The identifier of the element template." + }, + "description": { + "$id": "#/description", + "type": "string", + "description": "The description of the element template." + }, + "version": { + "$id": "#/version", + "type": "integer", + "description": "Optional version of the template. If you add a version to a template it will be considered unique based on its ID and version. Two templates can have the same ID if their version is different." + }, + "isDefault": { + "$id": "#/isDefault", + "type": "boolean", + "description": "Indicates whether the element template is a default template." + }, + "appliesTo": { + "$id": "#/appliesTo", + "type": "array", + "description": "List of BPMN types the template can be applied to.", + "default": [], + "items": { + "$id": "#/appliesTo/items", + "type": "string", + "pattern": "^[\\w\\d]+:[\\w\\d]+$", + "allOf": [ + { + "examples": [ + "bpmn:Task", + "bpmn:ServiceTask", + "bpmn:SequenceFlow", + "bpmn:Process", + "bpmn:StartEvent", + "bpmn:Gateway" + ] + } + ] + } + }, + "elementType": { + "$id": "#/elementType", + "type": "object", + "description": "The BPMN type the element will be transformed into.", + "default": {}, + "required": [ + "value" + ], + "properties": { + "value": { + "$id": "#/elementType/value", + "type": "string", + "pattern": "^[\\w\\d]+:[\\w\\d]+$", + "allOf": [ + { + "examples": [ + "bpmn:ServiceTask", + "bpmn:UserTask", + "bpmn:StartEvent", + "bpmn:ExclusiveGateway", + "bpmn:ParallelGateway" + ] + } + ] + } + } + }, + "metadata": { + "$id": "#/metadata", + "type": "object", + "description": "Some custom properties for further configuration.", + "default": {} + }, + "entriesVisible": { + "$id": "#/entriesVisible", + "type": "boolean", + "description": "Select whether non-template entries are visible in the properties panel." + }, + "groups": { + "$id": "#/groups", + "type": "array", + "description": "Custom fields can be ordered together via groups.", + "allOf": [ + { + "examples": [ + [ + { + "id": "group-1", + "label": "My Group" + } + ] + ] + } + ], + "items": { + "$id": "#/groups/group", + "type": "object", + "default": {}, + "required": [ + "id", + "label" + ], + "properties": { + "id": { + "$id": "#/groups/group/id", + "type": "string", + "description": "The id of the custom group" + }, + "label": { + "$id": "#/groups/group/label", + "type": "string", + "description": "The label of the custom group" + } + } + } + }, + "documentationRef": { + "$id": "#/documentationRef", + "type": "string", + "pattern": "^(https|http)://.*" + } + } + } + ], + "properties": { + "properties": { + "$ref": "#/definitions/properties", + "$id": "#/properties" + }, + "icon": { + "$id": "#/icon", + "type": "object", + "description": "Custom icon to be shown on the element", + "default": {}, + "properties": { + "contents": { + "$id": "#/icon/contents", + "type": "string", + "description": "The URL of an icon.", + "pattern": "^(https?|data):.*" + } + }, + "required": [ + "contents" + ] + } + } + } + }, + "oneOf": [ + { + "description": "An element template configuration.", + "$ref": "#/definitions/template" + }, + { + "type": "array", + "description": "A list of element template configurations.", + "items": { + "$ref": "#/definitions/template" + } + } + ] +} diff --git a/documentation/documentation-c8-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt b/documentation/documentation-c8-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt new file mode 100644 index 0000000..da1607a --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/WorkerDocumentationGeneratorMojoTest.kt @@ -0,0 +1,67 @@ +package dev.bpmcrafters.processengine.worker.documentation + +import dev.bpmcrafters.processengine.worker.documentation.core.WorkerDocumentationGenerator +import dev.bpmcrafters.processengine.worker.documentation.generator.api.DocumentationFailedException +import org.apache.maven.plugin.MojoExecutionException +import org.apache.maven.project.MavenProject +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.Test +import org.mockito.kotlin.doThrow +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.verify +import java.io.File + +class WorkerDocumentationGeneratorMojoTest { + + @Test + fun `execute with clean true calls clean and generate`() { + val mojo = WorkerDocumentationGeneratorMojo().apply { + project = mock() + outputDirectory = mock() + clean = true + } + + val mockGenerator = mock() + mojo.generatorFactory = { _, _, _ -> mockGenerator } + + mojo.execute() + + verify(mockGenerator).clean() + verify(mockGenerator).generate() + } + + @Test + fun `execute with clean false calls only generate`() { + val mojo = WorkerDocumentationGeneratorMojo().apply { + project = mock() + outputDirectory = mock() + clean = false + } + + val mockGenerator = mock() + mojo.generatorFactory = { _, _, _ -> mockGenerator } + + mojo.execute() + + verify(mockGenerator, never()).clean() + verify(mockGenerator).generate() + } + + @Test + fun `execute wraps DocumentationFailedException into MojoExecutionException`() { + val mojo = WorkerDocumentationGeneratorMojo().apply { + project = mock() + outputDirectory = mock() + clean = false + } + + val failingGenerator = mock { + on { generate() } doThrow DocumentationFailedException("boom", null) + } + mojo.generatorFactory = { _, _, _ -> failingGenerator } + + assertThatThrownBy { mojo.execute() } + .isInstanceOf(MojoExecutionException::class.java) + } +} diff --git a/documentation/documentation-c8-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda8ElementTemplateGeneratorTest.kt b/documentation/documentation-c8-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda8ElementTemplateGeneratorTest.kt new file mode 100644 index 0000000..3b8439f --- /dev/null +++ b/documentation/documentation-c8-maven-plugin/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/engine/Camunda8ElementTemplateGeneratorTest.kt @@ -0,0 +1,59 @@ +package dev.bpmcrafters.processengine.worker.documentation.engine + +import dev.bpmcrafters.processengine.worker.documentation.api.PropertyType +import dev.bpmcrafters.processengine.worker.documentation.generator.api.InputValueNamingPolicy +import dev.bpmcrafters.processengine.worker.documentation.generator.api.ProcessEngineWorkerDocumentationInfo +import dev.bpmcrafters.processengine.worker.documentation.generator.api.ProcessEngineWorkerPropertyInfo +import dev.bpmcrafters.processengine.worker.documentation.generator.api.TargetPlattform +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +class Camunda8ElementTemplateGeneratorTest { + + @Test + fun `generate builds expected JSON and metadata`() { + val generator = Camunda8ElementTemplateGenerator(inputValueNamingPolicy = InputValueNamingPolicy.ATTRIBUTE_NAME) + + val info = ProcessEngineWorkerDocumentationInfo( + name = "My Worker", + description = "desc", + version = -1, + type = "myTopic", + inputProperties = listOf( + ProcessEngineWorkerPropertyInfo( + name = "foo", + label = "Foo", + type = PropertyType.STRING, + editable = true, + notEmpty = false + ) + ), + outputProperties = listOf( + ProcessEngineWorkerPropertyInfo( + name = "bar", + label = "Bar", + type = PropertyType.STRING, + editable = true, + notEmpty = false + ) + ) + ) + + val result = generator.generate(info) + + assertThat(result) + .hasFieldOrPropertyWithValue("name", info.name) + .hasFieldOrPropertyWithValue("fileName", "My-Worker.json") + .hasFieldOrPropertyWithValue("engine", TargetPlattform.C8) + assertThat(result.content) + .contains("\"\$schema\"") + .contains("\"name\" : \"My Worker\"") + .contains("\"id\" : \"myTopic\"") + .contains("\"zeebe:taskDefinition:type\"") + .contains("\"Topic\"") + .contains("\"myTopic\"") + .contains("Input: Foo") + .contains("Output: Bar") + } + +} diff --git a/documentation/documentation-core/pom.xml b/documentation/documentation-core/pom.xml index d7aacdb..9e36c6c 100644 --- a/documentation/documentation-core/pom.xml +++ b/documentation/documentation-core/pom.xml @@ -10,7 +10,7 @@ process-engine-worker-documentation-core - ${artifactId} + ${project.artifactId} 3.9.11 @@ -62,31 +62,11 @@ process-engine-worker-documentation-api ${project.version} + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-generator-api + ${project.version} + - - - - org.jsonschema2pojo - jsonschema2pojo-maven-plugin - 1.2.2 - - ${basedir}/src/main/resources/schema - dev.bpmcrafters.processengine.worker.documentation.c7.elementtemplates.gen - true - true - - - - generate-sources - - generate - - - - - - - - diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/EngineSpecificConfig.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/EngineSpecificConfig.kt deleted file mode 100644 index 5139665..0000000 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/EngineSpecificConfig.kt +++ /dev/null @@ -1,5 +0,0 @@ -package dev.bpmcrafters.processengine.worker.documentation.core - -data class EngineSpecificConfig( - val c7: C7Config = C7Config() -) diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/InputValueNamingPolicy.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/InputValueNamingPolicy.kt deleted file mode 100644 index e8a4ed1..0000000 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/InputValueNamingPolicy.kt +++ /dev/null @@ -1,6 +0,0 @@ -package dev.bpmcrafters.processengine.worker.documentation.core - -enum class InputValueNamingPolicy { - EMPTY, - ATTRIBUTE_NAME -} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/SchemaJsonConverter.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/SchemaJsonConverter.kt new file mode 100644 index 0000000..b6229dc --- /dev/null +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/SchemaJsonConverter.kt @@ -0,0 +1,26 @@ +package dev.bpmcrafters.processengine.worker.documentation.core + +import com.fasterxml.jackson.core.JsonProcessingException +import com.fasterxml.jackson.databind.MapperFeature +import com.fasterxml.jackson.databind.json.JsonMapper + +class SchemaJsonConverter { + + companion object { + fun toJsonString(jsonSchema: String, content: T, contentClass: Class): String { + try { + val jsonSchema = "https://unpkg.com/@camunda/element-templates-json-schema@0.1.0/resources/schema.json" + val mapper = JsonMapper.builder() + .configure(MapperFeature.SORT_CREATOR_PROPERTIES_FIRST, true) + .addMixIn(contentClass, SchemaMixin::class.java) + .build() + val objectWriter = mapper.writerFor(contentClass) + .withAttribute("\$schema", jsonSchema) + return objectWriter.withDefaultPrettyPrinter().writeValueAsString(content) + } catch (e: JsonProcessingException) { + throw RuntimeException("Could not generate json string!", e) + } + } + } + +} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/SchemaMixin.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/SchemaMixin.kt similarity index 77% rename from documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/SchemaMixin.kt rename to documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/SchemaMixin.kt index 0c455b7..80cca3d 100644 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/engines/c7/SchemaMixin.kt +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/SchemaMixin.kt @@ -1,4 +1,4 @@ -package dev.bpmcrafters.processengine.worker.documentation.core.generator.engines.c7 +package dev.bpmcrafters.processengine.worker.documentation.core import com.fasterxml.jackson.databind.annotation.JsonAppend diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/TargetPlattform.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/TargetPlattform.kt deleted file mode 100644 index 5caedd9..0000000 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/TargetPlattform.kt +++ /dev/null @@ -1,5 +0,0 @@ -package dev.bpmcrafters.processengine.worker.documentation.core - -enum class TargetPlattform { - C7 -} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGenerator.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGenerator.kt index 662e4d8..1434414 100644 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGenerator.kt +++ b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGenerator.kt @@ -3,10 +3,10 @@ package dev.bpmcrafters.processengine.worker.documentation.core import dev.bpmcrafters.processengine.worker.ProcessEngineWorker import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerDocumentation import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerPropertyDocumentation -import dev.bpmcrafters.processengine.worker.documentation.core.generator.EngineDocumentationGenerator -import dev.bpmcrafters.processengine.worker.documentation.core.generator.ProcessEngineWorkerDocumentationInfo -import dev.bpmcrafters.processengine.worker.documentation.core.generator.ProcessEngineWorkerPropertyInfo -import dev.bpmcrafters.processengine.worker.documentation.core.generator.engines.c7.Camunda7ElementTemplateGenerator +import dev.bpmcrafters.processengine.worker.documentation.generator.api.DocumentationFailedException +import dev.bpmcrafters.processengine.worker.documentation.generator.api.EngineDocumentationGeneratorApi +import dev.bpmcrafters.processengine.worker.documentation.generator.api.ProcessEngineWorkerDocumentationInfo +import dev.bpmcrafters.processengine.worker.documentation.generator.api.ProcessEngineWorkerPropertyInfo import org.apache.commons.io.FileUtils import org.apache.maven.project.MavenProject import org.reflections.Reflections @@ -20,16 +20,10 @@ import java.net.URLClassLoader class WorkerDocumentationGenerator( val project: MavenProject, - val engine: TargetPlattform, val outputDirectory: File, - val engineSpecificConfig: EngineSpecificConfig, - val inputValueNamingPolicy: InputValueNamingPolicy = InputValueNamingPolicy.EMPTY, + val engineDocumentationGenerator: EngineDocumentationGeneratorApi ) { - val engineDocumentationGenerators = listOf( - Camunda7ElementTemplateGenerator() - ) - /** * Clean the output directory */ @@ -57,10 +51,6 @@ class WorkerDocumentationGenerator( ) val workers = reflections.getMethodsAnnotatedWith(ProcessEngineWorker::class.java) - val engine = engineDocumentationGenerators - .filter { it.isSupported(engine) } - .let { if (it.size != 1) throw DocumentationFailedException("Expected exactly one engine documentation generator for $engine, but got ${it.size}", null) else it.first() } - // generate documentation for each worker workers.forEach { if (it.parameterTypes.size > 1) { @@ -83,7 +73,7 @@ class WorkerDocumentationGenerator( generateProperties(returnType) ) - val result = engine.generate(processEngineWorkerDocumentation, inputValueNamingPolicy, engineSpecificConfig) + val result = engineDocumentationGenerator.generate(processEngineWorkerDocumentation) FileUtils.createParentDirectories(outputDirectory) val workerDocumentation = File(outputDirectory, result.fileName) diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt deleted file mode 100644 index bb811ed..0000000 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/EngineDocumentationGenerator.kt +++ /dev/null @@ -1,13 +0,0 @@ -package dev.bpmcrafters.processengine.worker.documentation.core.generator - -import dev.bpmcrafters.processengine.worker.documentation.core.EngineSpecificConfig -import dev.bpmcrafters.processengine.worker.documentation.core.InputValueNamingPolicy -import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform - -interface EngineDocumentationGenerator { - - fun generate(processEngineWorkerDocumentationInfo: ProcessEngineWorkerDocumentationInfo, namingPolicy: InputValueNamingPolicy, engineSpecificConfig: EngineSpecificConfig): GenerationResult - - fun isSupported(targetPlattform: TargetPlattform): Boolean - -} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/GenerationResult.kt b/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/GenerationResult.kt deleted file mode 100644 index e13647e..0000000 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/GenerationResult.kt +++ /dev/null @@ -1,11 +0,0 @@ -package dev.bpmcrafters.processengine.worker.documentation.core.generator - -import dev.bpmcrafters.processengine.worker.documentation.core.TargetPlattform - -data class GenerationResult( - val name: String, - val version : Int, - val content: String, - val fileName: String, - val engine: TargetPlattform -) diff --git a/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGeneratorTest.kt b/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGeneratorTest.kt index bf255e6..91a2347 100644 --- a/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGeneratorTest.kt +++ b/documentation/documentation-core/src/test/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/WorkerDocumentationGeneratorTest.kt @@ -3,12 +3,15 @@ package dev.bpmcrafters.processengine.worker.documentation.core import dev.bpmcrafters.processengine.worker.ProcessEngineWorker import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerDocumentation import dev.bpmcrafters.processengine.worker.documentation.api.ProcessEngineWorkerPropertyDocumentation +import dev.bpmcrafters.processengine.worker.documentation.generator.api.EngineDocumentationGeneratorApi +import dev.bpmcrafters.processengine.worker.documentation.generator.api.GenerationResult +import dev.bpmcrafters.processengine.worker.documentation.generator.api.TargetPlattform import org.apache.maven.project.MavenProject import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.io.TempDir -import org.mockito.kotlin.doReturn -import org.mockito.kotlin.mock +import org.mockito.Mockito.`when` +import org.mockito.kotlin.* import java.io.File class WorkerDocumentationGeneratorTest { @@ -31,6 +34,14 @@ class WorkerDocumentationGeneratorTest { @TempDir lateinit var tempDir: File + private val generationResult = GenerationResult( + name = "Test Worker", + fileName = "Test-Worker.json", + content = "test", + version = 0, + engine = TargetPlattform.C7 + ) + @Test fun `generate creates element template file for annotated worker`() { val testClassesPath = File(this::class.java.protectionDomain.codeSource.location.toURI()).path @@ -39,26 +50,23 @@ class WorkerDocumentationGeneratorTest { on { compileClasspathElements } doReturn(listOf(testClassesPath)) } + val engineGenerator = mock() + `when`(engineGenerator.generate(any())).thenReturn(generationResult) + val generator = WorkerDocumentationGenerator( project = project, - engine = TargetPlattform.C7, outputDirectory = tempDir, - engineSpecificConfig = EngineSpecificConfig(), - inputValueNamingPolicy = InputValueNamingPolicy.EMPTY + engineGenerator ) - // when generator.generate() - // then val expectedFile = File(tempDir, "Test-Worker.json") assertThat(expectedFile).exists() val content = expectedFile.readText() assertThat(content) - .contains("\"name\" : \"Test Worker\"") - .contains("\"id\" : \"testTopic\"") - .contains("Input: In Label") - .contains("Output: Out Label") + .isEqualTo("test") + verify(engineGenerator).generate(any()) } @Test @@ -67,6 +75,9 @@ class WorkerDocumentationGeneratorTest { on { compileClasspathElements } doReturn(emptyList()) } + val engineGenerator = mock() + `when`(engineGenerator.generate(any())).thenReturn(generationResult) + // create a file inside val testFile = File(tempDir, "some.txt").writeText("data") assertThat(tempDir) @@ -75,15 +86,14 @@ class WorkerDocumentationGeneratorTest { val generator = WorkerDocumentationGenerator( project = project, - engine = TargetPlattform.C7, outputDirectory = tempDir, - engineSpecificConfig = EngineSpecificConfig(), - inputValueNamingPolicy = InputValueNamingPolicy.EMPTY + engineGenerator ) generator.clean() assertThat(tempDir.exists()) .isFalse() + verify(engineGenerator, never()).generate(any()) } } diff --git a/documentation/documentation-plugin/src/main/resources/schema/camunda-c7-element-template.json b/documentation/documentation-plugin/src/main/resources/schema/camunda-c7-element-template.json deleted file mode 100644 index 538ec46..0000000 --- a/documentation/documentation-plugin/src/main/resources/schema/camunda-c7-element-template.json +++ /dev/null @@ -1,540 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema", - "$id": "http://camunda.org/schema/element-templates/1.0", - "type": "object", - "title": "Element Template Schema", - "description": "An element template definition", - "required": [ - "name", - "id", - "appliesTo", - "properties" - ], - "properties": { - "name": { - "$id": "#/name", - "type": "string", - "title": "element template name", - "description": "The name of the element template" - }, - "id": { - "$id": "#/id", - "type": "string", - "title": "element template id", - "description": "The identifier of the element template" - }, - "description": { - "$id": "#/description", - "type": "string", - "title": "element template description", - "description": "The description of the element template" - }, - "version": { - "$id": "#/version", - "type": "number", - "title": "element template version", - "description": "The version of the element template" - }, - "isDefault": { - "$id": "#/isDefault", - "type": "boolean", - "title": "element template is default", - "description": "Indicates whether the element template is a default template" - }, - "appliesTo": { - "$id": "#/appliesTo", - "type": "array", - "title": "element template applies to", - "description": "The definition for which element types the element template can be applied", - "default": [], - "items": { - "$id": "#/appliesTo/items", - "type": "string", - "pattern": "^(bpmn:)" - } - }, - "properties": { - "$id": "#/properties", - "type": "array", - "title": "element template properties", - "description": "The properties of the element template", - "default": [], - "items": { - "$id": "#/properties/property", - "type": "object", - "title": "element template property", - "description": "A property defined for the element template", - "default": {}, - "required": [ - "binding" - ], - "allOf": [ - { - "if": { - "properties": { - "type": { - "const": "Dropdown" - } - }, - "required": [ - "type" - ] - }, - "then": { - "required": [ - "choices" - ], - "errorMessage": "must provide choices=[] with \"Dropdown\" type" - } - }, - { - "if": { - "properties": { - "binding": { - "properties": { - "type": { - "const": "property" - } - }, - "required": [ - "type" - ] - } - }, - "required": [ - "binding" - ] - }, - "then": { - "properties": { - "type": { - "enum": [ - "String", - "Text", - "Hidden", - "Dropdown", - "Boolean" - ], - "errorMessage": "invalid property type ${0} for binding type \"property\"; must be any of { String, Text, Hidden, Dropdown, Boolean }" - } - } - } - }, - { - "if": { - "properties": { - "binding": { - "properties": { - "type": { - "const": "camunda:executionListener" - } - }, - "required": [ - "type" - ] - } - }, - "required": [ - "binding" - ] - }, - "then": { - "properties": { - "type": { - "enum": [ - "Hidden" - ], - "errorMessage": "invalid property type ${0} for binding type \"camunda:executionListener\"; must be \"Hidden\"" - } - } - } - }, - { - "if": { - "properties": { - "binding": { - "properties": { - "type": { - "enum": [ - "camunda:property", - "camunda:outputParameter", - "camunda:in", - "camunda:in:businessKey", - "camunda:out" - ] - } - }, - "required": [ - "type" - ] - } - }, - "required": [ - "binding" - ] - }, - "then": { - "properties": { - "type": { - "enum": [ - "String", - "Hidden", - "Dropdown" - ], - "errorMessage": "invalid property type ${0} for binding type ${1/binding/type}; must be any of { String, Hidden, Dropdown }" - } - } - } - }, - { - "if": { - "properties": { - "binding": { - "properties": { - "type": { - "enum": [ - "camunda:inputParameter", - "camunda:field" - ] - } - }, - "required": [ - "type" - ] - } - }, - "required": [ - "binding" - ] - }, - "then": { - "properties": { - "type": { - "enum": [ - "String", - "Text", - "Hidden", - "Dropdown" - ], - "errorMessage": "invalid property type ${0} for binding type ${1/binding/type}; must be any of { String, Text, Hidden, Dropdown }" - } - } - } - } - ], - "properties": { - "value": { - "$id": "#/properties/property/value", - "type": [ - "string", - "boolean" - ], - "title": "property value", - "description": "The value of the control field for the property" - }, - "description": { - "$id": "#/properties/property/description", - "type": "string", - "title": "property description", - "description": "The description of the control field" - }, - "label": { - "$id": "#/properties/property/label", - "type": "string", - "title": "property label", - "description": "The label of the control field for the property" - }, - "type": { - "$id": "#/properties/property/type", - "type": "string", - "title": "property type", - "description": "The type of the control field" - }, - "editable": { - "$id": "#/properties/property/editable", - "type": "boolean", - "title": "property editable", - "description": "Indicates whether the property is editable or not" - }, - "choices": { - "$id": "#/properties/property/choices", - "type": "array", - "title": "property choices", - "description": "The choices for dropdown properties", - "items": { - "$id": "#/properties/property/choices/item", - "type": "object", - "properties": { - "name": { - "$id": "#/properties/property/choices/item/name", - "type": "string", - "title": "choice name", - "description": "The name of the choice" - }, - "value": { - "$id": "#/properties/property/choices/item/value", - "type": "string", - "title": "choice value", - "description": "The value of the choice" - } - }, - "required": [ - "value", - "name" - ], - "errorMessage": "{ name, value } must be specified for \"Dropdown\" choices" - } - }, - "binding": { - "$id": "#/properties/property/binding", - "type": "object", - "title": "property binding", - "description": "A binding to a BPMN 2.0 property", - "required": [ - "type" - ], - "allOf": [ - { - "if": { - "properties": { - "type": { - "enum": [ - "property", - "camunda:property", - "camunda:inputParameter", - "camunda:field" - ] - } - }, - "required": [ - "type" - ] - }, - "then": { - "required": [ - "name" - ], - "errorMessage": "property.binding ${0/type} requires name" - } - }, - { - "if": { - "properties": { - "type": { - "const": "camunda:outputParameter" - } - }, - "required": [ - "type" - ] - }, - "then": { - "required": [ - "source" - ], - "errorMessage": "property.binding ${0/type} requires source" - } - }, - { - "if": { - "properties": { - "type": { - "const": "camunda:in" - } - }, - "required": [ - "type" - ] - }, - "then": { - "oneOf": [ - { - "required": [ - "variables" - ] - }, - { - "required": [ - "target" - ] - } - ], - "errorMessage": "property.binding ${0/type} requires variables or target" - } - }, - { - "if": { - "properties": { - "type": { - "const": "camunda:out" - } - }, - "required": [ - "type" - ] - }, - "then": { - "oneOf": [ - { - "required": [ - "variables" - ] - }, - { - "required": [ - "source" - ] - }, - { - "required": [ - "sourceExpression" - ] - } - ], - "errorMessage": "property.binding ${0/type} requires variables, sourceExpression or source" - } - } - ], - "properties": { - "type": { - "$id": "#/properties/property/binding/type", - "type": "string", - "title": "property binding type", - "enum": [ - "property", - "camunda:property", - "camunda:inputParameter", - "camunda:outputParameter", - "camunda:in", - "camunda:out", - "camunda:in:businessKey", - "camunda:executionListener", - "camunda:field" - ], - "errorMessage": "invalid property.binding type ${0}; must be any of { property, camunda:property, camunda:inputParameter, camunda:outputParameter, camunda:in, camunda:out, camunda:in:businessKey, camunda:executionListener, camunda:field }", - "description": "The type of the property binding" - }, - "name": { - "$id": "#/properties/property/binding/name", - "type": "string", - "title": "property binding name", - "description": "The name of binding xml property" - }, - "event": { - "$id": "#/properties/property/binding/event", - "type": "string", - "title": "property binding event", - "description": "The event type of an execution listener binding" - }, - "scriptFormat": { - "$id": "#/properties/property/binding/scriptFormat", - "type": "string", - "title": "property binding script format", - "description": "The format of a script property binding (camunda:outputParameter, camunda:inputParameter)" - }, - "source": { - "$id": "#/properties/property/binding/source", - "type": "string", - "title": "property binding source", - "description": "The source value of a property binding (camunda:outputParameter, camunda:out)" - }, - "target": { - "$id": "#/properties/property/binding/target", - "type": "string", - "title": "property binding target", - "description": "The target value to be mapped to (camunda:in)" - }, - "expression": { - "$id": "#/properties/property/binding/expression", - "type": "boolean", - "title": "property binding expression", - "description": "True indicates that the control field value is an expression (camunda:in, camunda:field)" - }, - "variables": { - "$id": "#/properties/property/binding/variables", - "type": "string", - "title": "property binding variables", - "enum": [ - "all", - "local" - ], - "description": "Either all or local indicating the variable mapping (camunda:in)" - }, - "sourceExpression": { - "$id": "#/properties/property/binding/sourceExpression", - "type": "string", - "title": "property binding source expression", - "description": "The string containing the expression for the source attribute (camunda:out)" - } - } - }, - "constraints": { - "$id": "#/properties/property/constraints", - "type": "object", - "title": "property constraints", - "description": "The validation constraints", - "properties": { - "notEmpty": { - "$id": "#/properties/property/constraints/notEmpty", - "type": "boolean", - "title": "property constraints not empty", - "description": "The control field must not be empty" - }, - "minLength": { - "$id": "#/properties/property/constraints/minLength", - "type": "string", - "title": "property constraints min length", - "description": "The minimal length for the control field value" - }, - "maxLength": { - "$id": "#/properties/property/constraints/maxLength", - "type": "string", - "title": "property constraints max length", - "description": "The maximal length for the control field value" - }, - "pattern": { - "$id": "#/properties/property/constraints/pattern", - "type": "object", - "title": "property constraints pattern", - "description": "A regular expression pattern for the constraints", - "properties": { - "value": { - "$id": "#/properties/property/constraints/pattern/value", - "type": "string", - "title": "property constraints pattern value", - "description": "The regular expression of the pattern constraint" - }, - "message": { - "$id": "#/properties/property/constraints/pattern/message", - "type": "string", - "title": "property constraints pattern message", - "description": "The validation message of the pattern constraint" - } - } - } - } - } - } - } - }, - "metadata": { - "$id": "#/metadata", - "type": "object", - "title": "element template metadata", - "description": "Some metadata for further configuration" - }, - "scopes": { - "$id": "#/scopes", - "type": "object", - "title": "element template scope", - "description": "Special scoped bindings that allow you to configure nested elements" - }, - "entriesVisible": { - "$id": "#/entriesVisible", - "deprecated": true, - "type": "object", - "title": "element template entries visible", - "description": "@Deprecated - Select which entries are visible in the properties panel" - } - } -} \ No newline at end of file diff --git a/documentation/generator-api/pom.xml b/documentation/generator-api/pom.xml new file mode 100644 index 0000000..fba139a --- /dev/null +++ b/documentation/generator-api/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation + 0.6.1-SNAPSHOT + + + process-engine-worker-documentation-generator-api + ${project.artifactId} + + + + dev.bpm-crafters.process-engine-worker + process-engine-worker-documentation-api + ${project.version} + + + + diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/BPMNElementType.kt b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/BPMNElementType.kt similarity index 71% rename from documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/BPMNElementType.kt rename to documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/BPMNElementType.kt index 992d032..073a6eb 100644 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/BPMNElementType.kt +++ b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/BPMNElementType.kt @@ -1,4 +1,4 @@ -package dev.bpmcrafters.processengine.worker.documentation.core.generator +package dev.bpmcrafters.processengine.worker.documentation.generator.api enum class BPMNElementType(val value: String) { BPMN_SERVICE_TASK("bpmn:ServiceTask"), diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/DocumentationFailedException.kt b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/DocumentationFailedException.kt similarity index 60% rename from documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/DocumentationFailedException.kt rename to documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/DocumentationFailedException.kt index 1a635c8..deed8b8 100644 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/DocumentationFailedException.kt +++ b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/DocumentationFailedException.kt @@ -1,4 +1,4 @@ -package dev.bpmcrafters.processengine.worker.documentation.core +package dev.bpmcrafters.processengine.worker.documentation.generator.api class DocumentationFailedException(message: String, cause: Throwable?): RuntimeException(message, cause) { } diff --git a/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/EngineDocumentationGeneratorApi.kt b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/EngineDocumentationGeneratorApi.kt new file mode 100644 index 0000000..6419381 --- /dev/null +++ b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/EngineDocumentationGeneratorApi.kt @@ -0,0 +1,7 @@ +package dev.bpmcrafters.processengine.worker.documentation.generator.api + +interface EngineDocumentationGeneratorApi { + + fun generate(processEngineWorkerDocumentationInfo: ProcessEngineWorkerDocumentationInfo): GenerationResult + +} diff --git a/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/GenerationResult.kt b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/GenerationResult.kt new file mode 100644 index 0000000..980d56f --- /dev/null +++ b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/GenerationResult.kt @@ -0,0 +1,9 @@ +package dev.bpmcrafters.processengine.worker.documentation.generator.api + +data class GenerationResult( + val name: String, + val version : Int, + val content: String, + val fileName: String, + val engine: TargetPlattform +) diff --git a/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/InputValueNamingPolicy.kt b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/InputValueNamingPolicy.kt new file mode 100644 index 0000000..6cdd07d --- /dev/null +++ b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/InputValueNamingPolicy.kt @@ -0,0 +1,6 @@ +package dev.bpmcrafters.processengine.worker.documentation.generator.api + +enum class InputValueNamingPolicy { + EMPTY, + ATTRIBUTE_NAME +} diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerDocumentationInfo.kt b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/ProcessEngineWorkerDocumentationInfo.kt similarity index 78% rename from documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerDocumentationInfo.kt rename to documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/ProcessEngineWorkerDocumentationInfo.kt index 86f76bc..f4d27e0 100644 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerDocumentationInfo.kt +++ b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/ProcessEngineWorkerDocumentationInfo.kt @@ -1,4 +1,4 @@ -package dev.bpmcrafters.processengine.worker.documentation.core.generator +package dev.bpmcrafters.processengine.worker.documentation.generator.api data class ProcessEngineWorkerDocumentationInfo( val name: String, diff --git a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerPropertyInfo.kt b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/ProcessEngineWorkerPropertyInfo.kt similarity index 76% rename from documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerPropertyInfo.kt rename to documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/ProcessEngineWorkerPropertyInfo.kt index dc0027e..6e5e75c 100644 --- a/documentation/documentation-core/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/core/generator/ProcessEngineWorkerPropertyInfo.kt +++ b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/ProcessEngineWorkerPropertyInfo.kt @@ -1,4 +1,4 @@ -package dev.bpmcrafters.processengine.worker.documentation.core.generator +package dev.bpmcrafters.processengine.worker.documentation.generator.api import dev.bpmcrafters.processengine.worker.documentation.api.PropertyType diff --git a/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/TargetPlattform.kt b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/TargetPlattform.kt new file mode 100644 index 0000000..b8eed43 --- /dev/null +++ b/documentation/generator-api/src/main/kotlin/dev/bpmcrafters/processengine/worker/documentation/generator/api/TargetPlattform.kt @@ -0,0 +1,6 @@ +package dev.bpmcrafters.processengine.worker.documentation.generator.api + +enum class TargetPlattform { + C7, + C8 +} diff --git a/documentation/pom.xml b/documentation/pom.xml index af7ecae..581ba1d 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -10,11 +10,13 @@ process-engine-worker-documentation - ${artifactId} + ${project.artifactId} documentation-api + generator-api documentation-core - documentation-plugin + documentation-c8-maven-plugin + documentation-c7-maven-plugin pom diff --git a/examples/camunda7-documentation-example/pom.xml b/examples/camunda7-documentation-example/pom.xml index f88c84b..af48a9c 100644 --- a/examples/camunda7-documentation-example/pom.xml +++ b/examples/camunda7-documentation-example/pom.xml @@ -33,18 +33,14 @@ dev.bpm-crafters.process-engine-worker - process-engine-worker-documentation-maven-plugin + process-engine-worker-documentation-c7-maven-plugin 0.6.1-SNAPSHOT - C7 - ATTRIBUTE_NAME true src/main/resources/bpmn/element-templates - - - true - - + + true + diff --git a/examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json b/examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json index a01338f..3e933ec 100644 --- a/examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json +++ b/examples/camunda7-documentation-example/src/main/resources/bpmn/element-templates/Example-Worker.json @@ -40,7 +40,7 @@ "name" : "camunda:asyncAfter" } }, { - "value" : "${exampleInput}", + "value" : "${}", "label" : "Input: Example Input", "type" : "String", "editable" : true,