From 41cc5f26e47537b1fa50452d4c4c9f7541849720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6rdes?= Date: Tue, 27 Oct 2026 15:20:14 +0100 Subject: [PATCH] JSON schema: move the element id mapping to docs.yaml and drop the legacy "id" keyword --- .../annot/generator/JsonSchemaGenerator.java | 11 +--------- .../annot/generator/YamlDocsGenerator.java | 20 +++++++++---------- .../kubernetes/model/AbstractSchema.java | 10 ---------- .../ApisYamlSchemaValidationTest.java | 12 ----------- 4 files changed, 10 insertions(+), 43 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 1f1028cebc..1cd89a2d54 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 @@ -133,16 +133,7 @@ private AbstractSchema createParser(Model model, MainInfo main, ElementInfo e parser = createRegularParser(model, main, elementInfo, parserName); } - return tagElementId(parser, elementInfo); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private static AbstractSchema tagElementId(AbstractSchema schema, ElementInfo elementInfo) { - String id = elementInfo.getId(); - if (id == null || id.isBlank()) return schema; - - ((AbstractSchema) schema).id(id); - return schema; + return parser; } private AbstractSchema createNoEnvelopeParser(Model model, MainInfo main, ElementInfo elementInfo, String parserName) { diff --git a/annot/src/main/java/com/predic8/membrane/annot/generator/YamlDocsGenerator.java b/annot/src/main/java/com/predic8/membrane/annot/generator/YamlDocsGenerator.java index 31ddb7a3cb..ccdedfb2cf 100644 --- a/annot/src/main/java/com/predic8/membrane/annot/generator/YamlDocsGenerator.java +++ b/annot/src/main/java/com/predic8/membrane/annot/generator/YamlDocsGenerator.java @@ -40,7 +40,7 @@ public class YamlDocsGenerator { - private static final int DOC_FORMAT_VERSION = 1; + private static final int DOC_FORMAT_VERSION = 2; private static final String OUTPUT_FILE = "docs.yaml"; private static final ObjectMapper YAML_MAPPER = new ObjectMapper( @@ -88,6 +88,7 @@ private Object buildRoot(Map> byNamespace) { if (ed.name != null && !ed.name.isBlank()) { el.put("name", ed.name); } + el.put("jsonSchemaDef", ed.jsonSchemaDef); if (ed.doc != null && !ed.doc.isEmpty()) { el.put("doc", ed.doc); } @@ -128,14 +129,15 @@ private Map> collectMains(Model m) { Map> out = new TreeMap<>(); for (MainInfo main : m.getMains()) { - collect(main, out); + collect(m, main, out); } out.entrySet().removeIf(e -> e.getValue().isEmpty()); return out; } - private void collect(MainInfo main, Map> out) { + // Every element is listed, documented or not: the reference docs map JSON schema $defs keys to element ids through jsonSchemaDef. + private void collect(Model m, MainInfo main, Map> out) { Map elements = out.computeIfAbsent(main.getAnnotation().targetNamespace(), __ -> new TreeMap<>()); for (ElementInfo ei : main.getElements().values()) { @@ -144,19 +146,14 @@ private void collect(MainInfo main, Map> out) { Map> children = childDocs(ei); Map otherAttrs = otherAttributesDoc(ei); - if (!isHasAnyDoc(elementDoc, attrs, children, otherAttrs)) continue; - - elements.put(ei.getId(), getElementDoc(ei, elementDoc, attrs, children, otherAttrs)); + elements.put(ei.getId(), getElementDoc(ei, ei.getXSDTypeName(m), elementDoc, attrs, children, otherAttrs)); } } - private static boolean isHasAnyDoc(Map elementDoc, Map> attrs, Map> children, Map otherAttrs) { - return !elementDoc.isEmpty() || !attrs.isEmpty() || !children.isEmpty() || !otherAttrs.isEmpty(); - } - - private static @NotNull ElementDoc getElementDoc(ElementInfo ei, Map elementDoc, Map> attrs, Map> children, Map otherAttrs) { + private static @NotNull ElementDoc getElementDoc(ElementInfo ei, String jsonSchemaDef, Map elementDoc, Map> attrs, Map> children, Map otherAttrs) { ElementDoc ed = new ElementDoc(); ed.name = ei.getAnnotation() != null ? ei.getAnnotation().name() : null; + ed.jsonSchemaDef = jsonSchemaDef; ed.doc = elementDoc; ed.attributes = attrs; ed.children = children; @@ -204,6 +201,7 @@ private Map docMap(Doc doc) { private static final class ElementDoc { String name; + String jsonSchemaDef; Map doc = Map.of(); Map> attributes = Map.of(); Map> children = Map.of(); diff --git a/annot/src/main/java/com/predic8/membrane/annot/generator/kubernetes/model/AbstractSchema.java b/annot/src/main/java/com/predic8/membrane/annot/generator/kubernetes/model/AbstractSchema.java index 30a3a1053b..f00554c365 100644 --- a/annot/src/main/java/com/predic8/membrane/annot/generator/kubernetes/model/AbstractSchema.java +++ b/annot/src/main/java/com/predic8/membrane/annot/generator/kubernetes/model/AbstractSchema.java @@ -25,7 +25,6 @@ public abstract class AbstractSchema> implements ISc protected String title; protected String name; - protected String id; protected String type; protected String description; protected List typeList; @@ -77,11 +76,6 @@ public T name(String name) { return self(); } - public T id(String id) { - this.id = id; - return self(); - } - public T type(String type) { this.type = type; this.typeList = null; @@ -117,10 +111,6 @@ public ObjectNode json(ObjectNode node) { node.put("type", type); } - if (id != null && !id.isBlank()) { - node.put("id", id); - } - return node; } diff --git a/distribution/src/test/java/com/predic8/membrane/examples/ApisYamlSchemaValidationTest.java b/distribution/src/test/java/com/predic8/membrane/examples/ApisYamlSchemaValidationTest.java index 8c9a45d409..2d279b2501 100644 --- a/distribution/src/test/java/com/predic8/membrane/examples/ApisYamlSchemaValidationTest.java +++ b/distribution/src/test/java/com/predic8/membrane/examples/ApisYamlSchemaValidationTest.java @@ -17,7 +17,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.MappingIterator; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.networknt.schema.Error; import com.networknt.schema.Schema; @@ -74,7 +73,6 @@ class ApisYamlSchemaValidationTest { if (in == null) throw new IOException("Schema not found on classpath: " + SCHEMA_CLASSPATH); JsonNode schemaNode = new ObjectMapper().readTree(in); - stripLegacyIdKeyword(schemaNode); SchemaRegistry registry = SchemaRegistry.withDefaultDialect(DRAFT_2020_12); SCHEMA = registry.getSchema(SchemaLocation.of(SCHEMA_CLASSPATH), schemaNode); SCHEMA.initializeValidators(); @@ -83,16 +81,6 @@ class ApisYamlSchemaValidationTest { } } - private static void stripLegacyIdKeyword(JsonNode schemaNode) { - JsonNode defs = schemaNode.get("$defs"); - if (defs == null) - return; - defs.forEach(def -> { - if (def instanceof ObjectNode obj) - obj.remove("id"); - }); - } - static Stream getApisYamlConfigs() { List roots = List.of("examples", "tutorials"); return roots.stream()