From 94cfe6462dc1b4de67a284450e595ff1e712db83 Mon Sep 17 00:00:00 2001 From: Kai Hudalla Date: Mon, 24 Aug 2026 14:58:23 +0200 Subject: [PATCH 1/3] 19 Update to AsciidoctorJ 3.0.1 Replaced invocations of StructuralNode.findBy() with manual traversal of child nodes because findBy() seems to be broken in AsciidoctorJ 3.0.1. This should not have much impact on runtime efficiency because findBy() would have to traverse the child nodes anyway, and we only care about direct children anyway, whose number should usually be quite small. --- .vscode/settings.json | 2 +- doc/changes/changes_0.3.2.md | 1 + pom.xml | 2 +- .../importer/asciidoc/AsciiDocImporter.java | 61 ++++++++++++------- .../asciidoc/AsciiDocImporterTest.java | 8 +-- 5 files changed, 45 insertions(+), 29 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 4f07762..11fdda4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -21,5 +21,5 @@ "-Djava.util.logging.config.file=src/test/resources/logging.properties" ] }, - "asciidoc.antora.enableAntoraSupport": false + "asciidoc.antora.showEnableAntoraPrompt": false } diff --git a/doc/changes/changes_0.3.2.md b/doc/changes/changes_0.3.2.md index 837151e..8008c45 100644 --- a/doc/changes/changes_0.3.2.md +++ b/doc/changes/changes_0.3.2.md @@ -9,3 +9,4 @@ We upgraded the OFT dependency to version 4.8.0. ## Refactoring * Updated OFT to 4.8.0 +* Updated asciidoctorj dependency to 3.0.1 diff --git a/pom.xml b/pom.xml index c6de7ce..af9dfcf 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ 4.8.0 0.8.14 - 3.0.0 + 3.0.1 itsallcode https://sonarcloud.io ${git.commit.time} diff --git a/src/main/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporter.java b/src/main/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporter.java index 7d8fd8d..fa55d96 100644 --- a/src/main/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporter.java +++ b/src/main/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporter.java @@ -26,13 +26,12 @@ class AsciiDocImporter implements Importer private static final String CONTENT_MODEL_SIMPLE = "simple"; - private static final String KEY_ROLE = "role"; + private static final String NODE_NAME_PARAGRAPH = "paragraph"; - private static final String ROLE_COMMENT = ":comment"; - private static final String ROLE_DESCRIPTION = ":description"; - private static final String ROLE_RATIONALE = ":rationale"; - - private static final String ROLE_NAME_SPECITEM = "specitem"; + private static final String ROLE_COMMENT = "comment"; + private static final String ROLE_DESCRIPTION = "description"; + private static final String ROLE_RATIONALE = "rationale"; + private static final String ROLE_SPECITEM = "specitem"; private static final Logger LOG = Logger.getLogger(AsciiDocImporter.class.getName()); @@ -79,6 +78,8 @@ private Location getLocation(final StructuralNode block) private Optional getStringContent(final StructuralNode node) { + LOG.finer(() -> "getting content for node [content model: %s, name: %s, location: %s]" + .formatted(node.getContentModel(), node.getNodeName(), getLocation(node))); switch (node.getContentModel()) { case CONTENT_MODEL_SIMPLE: @@ -139,38 +140,52 @@ private void processSpecificationItemTags(final StructuralNode block) // [impl->dsn~adoc-specification-item-description~1] private void processSpecificationItemDescription(final StructuralNode block) { - final Optional descriptionBlock = block.findBy(Map.of(KEY_ROLE, ROLE_DESCRIPTION)).stream() + final Optional descriptionBlock = block.getBlocks().stream() + .filter(node -> !ROLE_RATIONALE.equals(node.getRole())) + .filter(node -> !ROLE_COMMENT.equals(node.getRole())) + .filter(node -> ROLE_DESCRIPTION.equals(node.getRole()) + || NODE_NAME_PARAGRAPH.equals(node.getNodeName())) .findFirst(); - descriptionBlock - .or(() -> block.getBlocks().stream() - .filter(node -> !"rationale".equals(node.getRole()) && !"comment".equals(node.getRole())) - .findFirst()) - .flatMap(this::getStringContent) - .ifPresent(listener::appendDescription); + + descriptionBlock.flatMap(this::getStringContent) + .ifPresent(description -> { + LOG.finer(() -> "adding description to spec item: %s".formatted(description)); + listener.appendDescription(description); + }); } // [impl->dsn~adoc-specification-item-rationale~1] private void processSpecificationItemRationale(final StructuralNode block) { - block.findBy(Map.of(KEY_ROLE, ROLE_RATIONALE)).stream().findFirst() + block.getBlocks().stream() + .filter(node -> ROLE_RATIONALE.equals(node.getRole())) + .findFirst() .flatMap(this::getStringContent) - .ifPresent(listener::appendRationale); + .ifPresent(rationale -> { + LOG.finer(() -> "adding rationale to spec item: %s".formatted(rationale)); + listener.appendRationale(rationale); + }); } // [impl->dsn~adoc-specification-item-comment~1] private void processSpecificationItemComment(final StructuralNode block) { - block.findBy(Map.of(KEY_ROLE, ROLE_COMMENT)).stream().findFirst() + block.getBlocks().stream() + .filter(node -> ROLE_COMMENT.equals(node.getRole())) + .findFirst() .flatMap(this::getStringContent) - .ifPresent(listener::appendComment); + .ifPresent(comment -> { + LOG.finer(() -> "adding comment to spec item: %s".formatted(comment)); + listener.appendComment(comment); + }); } private void processSpecificationItemBlock(final String sid, final StructuralNode block) { final SpecificationItemId specItemId = new SpecificationItemId.Builder(sid).build(); final Location location = getLocation(block); - LOG.fine(() -> String.format("adding specification item [ID: %s, location: %s]", specItemId, - location)); + LOG.fine(() -> String.format("adding specification item [ID: %s, block name: %s, location: %s]", specItemId, + block.getNodeName(), location)); this.listener.beginSpecificationItem(); this.listener.setId(specItemId); @@ -220,8 +235,8 @@ private void processForwardingBlock(final String skippedType, final StructuralNo // [impl->dsn~adoc-artifact-forwarding-notation~1] private void processSpecificationItem(final StructuralNode block) { - LOG.fine(() -> String.format("found specitem block [id: %s]", - block.getId())); + LOG.fine(() -> String.format("found specitem block [id: %s, name: %s]", + block.getId(), block.getNodeName())); Optional.ofNullable(block.getAttribute(ATTRIBUTE_OFT_SID)) .filter(String.class::isInstance) @@ -248,7 +263,7 @@ private void processDocument(final Document document) private void processBlock(final StructuralNode block) { - if (block.hasRole(ROLE_NAME_SPECITEM)) + if (block.hasRole(ROLE_SPECITEM)) { processSpecificationItem(block); } @@ -280,7 +295,7 @@ private void processTable(final Table table) private Document parseAsciiDoc() { final Options options = Options.builder().sourcemap(true).build(); - try (final Asciidoctor asciidoctor = Asciidoctor.Factory.create()) + try (Asciidoctor asciidoctor = Asciidoctor.Factory.create()) { if (this.file != null) { diff --git a/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterTest.java b/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterTest.java index 8400825..956abac 100644 --- a/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterTest.java +++ b/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterTest.java @@ -65,7 +65,7 @@ void testImporterIgnoresSpecItemWithoutId(final String content) @ValueSource(strings = { """ - # Spec + # Spec 1 [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"] ## A Requirement @@ -79,7 +79,7 @@ void testImporterIgnoresSpecItemWithoutId(final String content) A comment """, """ - # Spec + # Spec 2 [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"] ## A Requirement @@ -94,7 +94,7 @@ void testImporterIgnoresSpecItemWithoutId(final String content) A comment """, """ - # Spec + # Spec 3 .A Requirement [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"] @@ -110,7 +110,7 @@ void testImporterIgnoresSpecItemWithoutId(final String content) ==== """, """ - # Spec + # Spec 4 .A Requirement [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"] From f5e25117d9b21f9751525fce11ecec8f4a3a3b8d Mon Sep 17 00:00:00 2001 From: Kai Hudalla Date: Wed, 26 Aug 2026 13:55:25 +0200 Subject: [PATCH 2/3] 19 Fix links --- README.md | 4 ++-- doc/developer_guide.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 16518ee..868d4fa 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ _[Place a screenshot of a tracing report generated using this plugin here]_ ## Project Information [![Build](https://github.com/itsallcode/openfasttrace-asciidoc-plugin/actions/workflows/build.yml/badge.svg)](https://github.com/itsallcode/openfasttrace-asciidoc-plugin/actions/workflows/build.yml) -[![Maven Central Version](https://img.shields.io/maven-central/v/org.itsallcode/openfasttrace-asciidoc-plugin)](https://search.maven.org/artifact/org.itsallcode/openfasttrace-asciidoc-plugin) +[![Maven Central Version](https://img.shields.io/maven-central/v/org.itsallcode/openfasttrace-asciidoc-plugin)](https://central.sonatype.com/artifact/org.itsallcode/openfasttrace-asciidoc-plugin) Sonarcloud status: @@ -64,7 +64,7 @@ For more detailed information on how to use OpenFastTrack with AsciiDoc Plugin, The OpenFastTrace AsciiDoc Plugin is supplied as a Java Archive (JAR) which can be obtained from: -* [Maven Central](#) +* [Maven Central](https://central.sonatype.com/artifact/org.itsallcode/openfasttrace-asciidoc-plugin) * [GitHub](https://github.com/itsallcode/openfasttrace-asciidoc-plugin/releases) More details about adding the plugin to an existing establishment are outlined in the [developer guide](doc/developer_guide.md). diff --git a/doc/developer_guide.md b/doc/developer_guide.md index 0ca0452..a535fe5 100644 --- a/doc/developer_guide.md +++ b/doc/developer_guide.md @@ -39,7 +39,7 @@ The list below shows all build time dependencies in alphabetical order. Note tha | Dependency | Purpose | License | | ---------------------------------------------------------------------------- | --------------------------------------- | ----------------------------- | | [Hamcrest Auto Matcher](https://github.com/itsallcode/hamcrest-auto-matcher) | Speed-up for building Hamcrest matchers | GNU General Public License V3 | -| [JUnit](https://junit.org/junit5) | Unit testing framework | Eclipse Public License 1.0 | +| [JUnit](https://docs.junit.org/current/user-guide/) | Unit testing framework | Eclipse Public License 1.0 | | [Mockito](https://github.com/mockito/mockito) | Mocking framework | MIT License | ### Runtime Dependencies From 2fad7a9c381adb99a743f635f3e8bce4f031c26f Mon Sep 17 00:00:00 2001 From: Kai Hudalla Date: Wed, 26 Aug 2026 13:58:33 +0200 Subject: [PATCH 3/3] 19 Reduce Log level --- .../openfasttrace/importer/asciidoc/AsciiDocImporter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporter.java b/src/main/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporter.java index fa55d96..59d3d02 100644 --- a/src/main/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporter.java +++ b/src/main/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporter.java @@ -78,7 +78,7 @@ private Location getLocation(final StructuralNode block) private Optional getStringContent(final StructuralNode node) { - LOG.finer(() -> "getting content for node [content model: %s, name: %s, location: %s]" + LOG.finest(() -> "getting content for node [content model: %s, name: %s, location: %s]" .formatted(node.getContentModel(), node.getNodeName(), getLocation(node))); switch (node.getContentModel()) { @@ -149,7 +149,7 @@ private void processSpecificationItemDescription(final StructuralNode block) descriptionBlock.flatMap(this::getStringContent) .ifPresent(description -> { - LOG.finer(() -> "adding description to spec item: %s".formatted(description)); + LOG.finest(() -> "adding description to spec item: %s".formatted(description)); listener.appendDescription(description); }); } @@ -162,7 +162,7 @@ private void processSpecificationItemRationale(final StructuralNode block) .findFirst() .flatMap(this::getStringContent) .ifPresent(rationale -> { - LOG.finer(() -> "adding rationale to spec item: %s".formatted(rationale)); + LOG.finest(() -> "adding rationale to spec item: %s".formatted(rationale)); listener.appendRationale(rationale); }); } @@ -175,7 +175,7 @@ private void processSpecificationItemComment(final StructuralNode block) .findFirst() .flatMap(this::getStringContent) .ifPresent(comment -> { - LOG.finer(() -> "adding comment to spec item: %s".formatted(comment)); + LOG.finest(() -> "adding comment to spec item: %s".formatted(comment)); listener.appendComment(comment); }); }