From 88789e0ad5deaab5d4a1d7c063ad8513c996bd5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6rdes?= Date: Mon, 23 Feb 2026 10:35:20 +0100 Subject: [PATCH 1/3] Enhance schema generation to always reference flowParser for interceptor list --- .../annot/generator/JsonSchemaGenerator.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/annot/src/main/java/com/predic8/membrane/annot/generator/JsonSchemaGenerator.java b/annot/src/main/java/com/predic8/membrane/annot/generator/JsonSchemaGenerator.java index 18c62367af..7b15a55f58 100644 --- a/annot/src/main/java/com/predic8/membrane/annot/generator/JsonSchemaGenerator.java +++ b/annot/src/main/java/com/predic8/membrane/annot/generator/JsonSchemaGenerator.java @@ -44,6 +44,7 @@ public class JsonSchemaGenerator extends AbstractGrammar { public static final String MEMBRANE_SCHEMA_JSON_FILENAME = "membrane.schema.json"; public static final String COMPONENTS = "components"; + private static final String INTERCEPTOR_FQN = "com.predic8.membrane.core.interceptor.Interceptor"; // TODO keep this pattern or allow *? public static final String COMPONENT_ID_PATTERN = "^[A-Za-z_][A-Za-z0-9_-]*$"; @@ -127,6 +128,9 @@ private AbstractSchema createParser(Model m, MainInfo main, ElementInfo eleme componentAdded.put(childName, true); } + if (shouldGenerateFlowParserType(child)) { + return ref(parserName).ref("#/$defs/flowParser"); + } return ref(parserName).ref("#/$defs/%sParser".formatted(childName)); } @@ -352,7 +356,14 @@ private boolean isComponentsList(ElementInfo parent, ChildElementInfo cei) { } private boolean shouldGenerateFlowParserType(ChildElementInfo cei) { - return "flow".equals(cei.getPropertyName()) && !isFlowFromWebSocket(cei); + if (!cei.isList()) return false; + if (isFlowFromWebSocket(cei)) return false; + + TypeElement interceptor = processingEnv.getElementUtils().getTypeElement(INTERCEPTOR_FQN); + if (interceptor == null) { + return INTERCEPTOR_FQN.equals(cei.getTypeDeclaration().getQualifiedName().toString()); + } + return processingEnv.getTypeUtils().isAssignable(cei.getTypeDeclaration().asType(), interceptor.asType()); } boolean isFlowFromWebSocket(ChildElementInfo cei) { @@ -364,7 +375,7 @@ private AbstractSchema processList(ElementInfo i, AbstractSchema so, Child SchemaObject items = object("items"); if (shouldGenerateFlowParserType(cei)) { - addFlowParserRef(so, sos); + addFlowParserRef(so, cei.getPropertyName(), sos); return items; } @@ -381,15 +392,16 @@ private AbstractSchema processList(ElementInfo i, AbstractSchema so, Child return items; } - private void addFlowParserRef(AbstractSchema so, List> sos) { + private void addFlowParserRef(AbstractSchema parentSchema, String propertyName, List> sos) { if (!flowDefCreated) { schema.definition(array("flowParser").items(anyOf(sos))); flowDefCreated = true; } - SchemaRef ref = ref("flow").ref("#/$defs/flowParser"); - if (so instanceof SchemaArray sa) { + SchemaRef ref = ref(propertyName).ref("#/$defs/flowParser"); + + if (parentSchema instanceof SchemaArray sa) { sa.items(ref); - } else if (so instanceof SchemaObject sObj) { + } else if (parentSchema instanceof SchemaObject sObj) { sObj.property(ref); } } From 034a99a68d8530af3b60b35971a4465057a6a641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6rdes?= Date: Mon, 23 Feb 2026 12:44:38 +0100 Subject: [PATCH 2/3] Add components javadoc --- .../annot/generator/BeanClassGenerator.java | 8 +++----- .../annot/generator/ComponentClassGenerator.java | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/annot/src/main/java/com/predic8/membrane/annot/generator/BeanClassGenerator.java b/annot/src/main/java/com/predic8/membrane/annot/generator/BeanClassGenerator.java index 75d9ddaa60..3b4a28a396 100644 --- a/annot/src/main/java/com/predic8/membrane/annot/generator/BeanClassGenerator.java +++ b/annot/src/main/java/com/predic8/membrane/annot/generator/BeanClassGenerator.java @@ -46,12 +46,10 @@ protected String getClassImpl() { * class: com.example.MyInterceptor * scope: SINGLETON * constructorArgs: - * - constructorArg: - * value: foo + * - value: foo * properties: - * - property: - * name: bar - * value: baz + * - name: bar + * value: baz */ @MCElement(name = "bean") public class Bean { diff --git a/annot/src/main/java/com/predic8/membrane/annot/generator/ComponentClassGenerator.java b/annot/src/main/java/com/predic8/membrane/annot/generator/ComponentClassGenerator.java index 83bba7f6d3..716788a5d6 100644 --- a/annot/src/main/java/com/predic8/membrane/annot/generator/ComponentClassGenerator.java +++ b/annot/src/main/java/com/predic8/membrane/annot/generator/ComponentClassGenerator.java @@ -36,6 +36,20 @@ protected String getClassImpl() { import java.util.Map; + /** + * @description Defines reusable, named components that can be referenced from other sections (e.g., via $ref). + * @yaml

+                 * components:
+                 *   demoComponent: # id for the component
+                 *     log: {} # referencable plugin
+                 * ---
+                 * api:
+                 *   port: 2000
+                 *   flow:
+                 *     - $ref: '#/components/demoComponent' # references the demo component
+                 * 
+ * @topic 1. Proxies and Flow + */ @MCElement(name = "components", topLevel = true, component=false) public class Components { From fbc07f576e12f3881642d98eac82bb1a6122dbae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6rdes?= Date: Mon, 23 Feb 2026 16:02:12 +0100 Subject: [PATCH 3/3] fix typo --- .../membrane/annot/generator/ComponentClassGenerator.java | 2 +- distribution/examples/configuration/apis.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/annot/src/main/java/com/predic8/membrane/annot/generator/ComponentClassGenerator.java b/annot/src/main/java/com/predic8/membrane/annot/generator/ComponentClassGenerator.java index 716788a5d6..c9b87da544 100644 --- a/annot/src/main/java/com/predic8/membrane/annot/generator/ComponentClassGenerator.java +++ b/annot/src/main/java/com/predic8/membrane/annot/generator/ComponentClassGenerator.java @@ -41,7 +41,7 @@ protected String getClassImpl() { * @yaml

                  * components:
                  *   demoComponent: # id for the component
-                 *     log: {} # referencable plugin
+                 *     log: {} # referenceable plugin
                  * ---
                  * api:
                  *   port: 2000
diff --git a/distribution/examples/configuration/apis.yaml b/distribution/examples/configuration/apis.yaml
index 8dce64b295..c1bff405f1 100644
--- a/distribution/examples/configuration/apis.yaml
+++ b/distribution/examples/configuration/apis.yaml
@@ -37,7 +37,7 @@ global:
 components:
 
   demoComponent: # id for the component
-    log: {} # referencable plugin
+    log: {} # referenceable plugin
 
   jmx: # id for the bean
     bean: