From a3e362d78e3180ed64fc736605357894e8faf930 Mon Sep 17 00:00:00 2001
From: "jetbrains-junie[bot]"
<201638009+jetbrains-junie[bot]@users.noreply.github.com>
Date: Mon, 1 Dec 2025 17:28:53 +0000
Subject: [PATCH 1/3] fix(codegen): set group delimiter for deeply nested
components The MessageSubclass.xsl was fixed to correctly set the group
delimiter for nested components deeper than one level. The fix adds a
template to recurse within component definitions to find the delimiter tag.
This change ensures generated code such as NestedTwice.java now compiles with
a valid constructor.
---
.../org/quickfixj/codegenerator/MessageSubclass.xsl | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/quickfixj-codegenerator/src/main/resources/org/quickfixj/codegenerator/MessageSubclass.xsl b/quickfixj-codegenerator/src/main/resources/org/quickfixj/codegenerator/MessageSubclass.xsl
index 4333c3b62c..b33bb7fd61 100644
--- a/quickfixj-codegenerator/src/main/resources/org/quickfixj/codegenerator/MessageSubclass.xsl
+++ b/quickfixj-codegenerator/src/main/resources/org/quickfixj/codegenerator/MessageSubclass.xsl
@@ -205,6 +205,15 @@ import quickfix.Group;
+
+
+
+
+
+
+
+
From 1564c662bac216f7f95f0a2b1fe3779b6082ffed Mon Sep 17 00:00:00 2001
From: "junie-eap[bot]"
Date: Mon, 1 Dec 2025 18:36:07 +0000
Subject: [PATCH 2/3] [issue-1089] test(codegen): add unit test for nested
group delimiter fix
A new unit test was added to verify the fix for setting the group delimiter in deeply nested components. A minimal FIX test dictionary modeling nested groups was created and used in the test. The test confirms that the generated code correctly uses the deepest nested field as the group delimiter, preventing regression.
---
.../NestedGroupDelimiterTest.java | 75 +++++++++++++++++++
.../src/test/resources/NESTED_FIX.xml | 31 ++++++++
2 files changed, 106 insertions(+)
create mode 100644 quickfixj-codegenerator/src/test/java/org/quickfixj/codegenerator/NestedGroupDelimiterTest.java
create mode 100644 quickfixj-codegenerator/src/test/resources/NESTED_FIX.xml
diff --git a/quickfixj-codegenerator/src/test/java/org/quickfixj/codegenerator/NestedGroupDelimiterTest.java b/quickfixj-codegenerator/src/test/java/org/quickfixj/codegenerator/NestedGroupDelimiterTest.java
new file mode 100644
index 0000000000..eba4652af8
--- /dev/null
+++ b/quickfixj-codegenerator/src/test/java/org/quickfixj/codegenerator/NestedGroupDelimiterTest.java
@@ -0,0 +1,75 @@
+package org.quickfixj.codegenerator;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Verifies that the code generator sets the correct group delimiter when the
+ * first element of a repeating group is a component that nests other components
+ * before the first concrete field appears.
+ *
+ * This covers the regression fixed in PR #1089 where the XSL must recurse into
+ * deeply nested components to locate the actual first field (delimiter).
+ */
+public class NestedGroupDelimiterTest {
+
+ private final File outputDirectory = new File("./target/test-output/");
+ private final File dictFile = new File("./src/test/resources/NESTED_FIX.xml");
+ private final File schemaDirectory = new File("./src/main/resources/org/quickfixj/codegenerator");
+
+ @Before
+ public void setup() throws IOException {
+ if (outputDirectory.exists()) {
+ FileUtils.cleanDirectory(outputDirectory);
+ } else {
+ outputDirectory.mkdirs();
+ }
+ }
+
+ @Test
+ public void generatesGroupWithDeeplyNestedDelimiter() throws Exception {
+ MessageCodeGenerator generator = new MessageCodeGenerator();
+ MessageCodeGenerator.Task task = new MessageCodeGenerator.Task();
+
+ task.setSpecification(dictFile);
+ task.setName(dictFile.getName());
+ task.setTransformDirectory(schemaDirectory);
+ task.setMessagePackage("quickfix.fixZZ");
+ task.setOutputBaseDirectory(outputDirectory);
+ task.setFieldPackage("quickfix.field");
+ task.setUtcTimestampPrecision(null);
+ task.setOverwrite(true);
+ task.setOrderedFields(true);
+ task.setDecimalGenerated(true);
+
+ try {
+ generator.generate(task);
+ } catch (MojoExecutionException e) {
+ // Surface with context for easier debugging in CI
+ throw new AssertionError("Code generation failed: " + e.getMessage(), e);
+ }
+
+ // Read the generated message class and assert the group constructor uses FieldA (1001) as delimiter
+ File generated = new File(outputDirectory, "quickfix/fixZZ/NestedGroupTest.java");
+ assertTrue("Expected generated message class not found: " + generated.getAbsolutePath(), generated.exists());
+
+ String java = FileUtils.readFileToString(generated, StandardCharsets.UTF_8);
+
+ // The group name is NoOuterGrp with counter tag 1000. The delimiter should be FieldA (1001),
+ // which is the first field reachable by recursing into components (InnerComponent -> DeepComponent -> FieldA)
+ // The generated constructor should therefore look like: super(1000, 1001, ORDER)
+ assertTrue(
+ "Group constructor should use 1001 as delimiter for NoOuterGrp (deeply nested first field)",
+ java.contains("public static class NoOuterGrp") &&
+ java.contains("super(1000, 1001, ORDER)")
+ );
+ }
+}
diff --git a/quickfixj-codegenerator/src/test/resources/NESTED_FIX.xml b/quickfixj-codegenerator/src/test/resources/NESTED_FIX.xml
new file mode 100644
index 0000000000..0bc085e5c3
--- /dev/null
+++ b/quickfixj-codegenerator/src/test/resources/NESTED_FIX.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From fc97673d79acc12b71f6a2dba254e174c1074739 Mon Sep 17 00:00:00 2001
From: "junie-eap[bot]"
Date: Tue, 2 Dec 2025 03:43:18 +0000
Subject: [PATCH 3/3] [issue-1089] test(codegen): fix exception handling in
NestedGroupDelimiterTest
The compilation error in NestedGroupDelimiterTest.java was fixed by replacing the catch of MojoExecutionException with CodeGenerationException and removing the unused import. All tests in the quickfixj-codegenerator module passed successfully after the fix. The change ensures correct exception handling matching the generator's behavior and preserves test assertions.
---
.../org/quickfixj/codegenerator/NestedGroupDelimiterTest.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/quickfixj-codegenerator/src/test/java/org/quickfixj/codegenerator/NestedGroupDelimiterTest.java b/quickfixj-codegenerator/src/test/java/org/quickfixj/codegenerator/NestedGroupDelimiterTest.java
index eba4652af8..83c27be8b5 100644
--- a/quickfixj-codegenerator/src/test/java/org/quickfixj/codegenerator/NestedGroupDelimiterTest.java
+++ b/quickfixj-codegenerator/src/test/java/org/quickfixj/codegenerator/NestedGroupDelimiterTest.java
@@ -7,7 +7,6 @@
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.FileUtils;
-import org.apache.maven.plugin.MojoExecutionException;
import org.junit.Before;
import org.junit.Test;
@@ -52,7 +51,7 @@ public void generatesGroupWithDeeplyNestedDelimiter() throws Exception {
try {
generator.generate(task);
- } catch (MojoExecutionException e) {
+ } catch (CodeGenerationException e) {
// Surface with context for easier debugging in CI
throw new AssertionError("Code generation failed: " + e.getMessage(), e);
}