Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 15, 2025

The XSLT template for finding group delimiters failed when the first element of a group was a component containing another component (nested ≥2 levels). The template matched group//component which only matched components as descendants of groups. During recursion into the global component tree, nodes lost their group ancestry and the template stopped matching, producing invalid code:

super(20001, , ORDER);  // Missing delimiter

Changes

  • MessageSubclass.xsl: Changed match="group//component" to match="component" in the group-delimiter template, enabling recursion through arbitrarily nested components
  • NestedComponentsTest.xml: Minimal FIX dictionary with Level1→Level2→Text component nesting structure
  • NestedComponentDelimiterTest.java: Regression test verifying correct delimiter resolution through nested components

Example

Given a FIX dictionary where:

  • NestedTwice component has a NoEntries(20001) group
  • Group's first element is Level1 component
  • Level1 contains Level2 component
  • Level2 contains Text(58) field

Generated code now correctly produces:

super(20001, 58, ORDER);  // Delimiter resolves to Text field

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • www.w3.org
    • Triggering command: /opt/hostedtoolcache/CodeQL/2.23.7/x64/codeql/tools/linux64/java/bin/java /opt/hostedtoolcache/CodeQL/2.23.7/x64/codeql/tools/linux64/java/bin/java -jar /opt/hostedtoolcache/CodeQL/2.23.7/x64/codeql/xml/tools/xml-extractor.jar --fileList=/home/REDACTED/work/quickfixj/.codeql-scratch/dbs/java/working/files-to-index9538710877081472329.list --sourceArchiveDir=/home/REDACTED/work/quickfixj/.codeql-scratch/dbs/java/src --outputDir=/home/REDACTED/work/quickfixj/.codeql-scratch/dbs/java/trap/java (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

Summary
Fix MessageSubclass.xsl so MessageCodeGenerator sets the group delimiter correctly when the first element of a group is a component whose first element is another component (nested > 1). Add a regression test using a minimal FIX spec to ensure the generated code uses the proper delimiter and compiles structurally.

Context

  • Repository: quickfix-j/quickfixj
  • Problem: Issue MessageCodeGenerator fails to set group delimiter for nested components #1084 reports generated code like:
    super(20001, , ORDER);
    when generating a group whose first child is a nested component-of-component. Current XSL uses a template match="group//component" in mode group-delimeter, which fails after the first recursion step (the next component node is resolved in the global /fix/components tree and no longer matches group//component). As a result, no delimiter is emitted.

Proposed changes

  1. XSLT fix (MessageSubclass.xsl)
  • Replace the component delimiter template that currently only matches descendants under a group:
    <xsl:template mode="group-delimeter" match="group//component"> ... </xsl:template>
    with a generalized version that matches any component node:
    <xsl:template mode="group-delimeter" match="component"> ... </xsl:template>
  • Keep existing field and group templates unchanged. This allows recursion across arbitrarily deep nested components to reach the first field (or nested group) and output its tag number correctly.
  1. Regression test (quickfixj-codegenerator)
  • Add a minimal FIX specification XML under test resources that defines:
    • fields: Text(58), NoEntries(20001)
    • components: Level2 contains field Text; Level1 contains component Level2; NestedTwice contains a group NoEntries whose first element is component Level1
    • a dummy message that references the NestedTwice component so code-generation includes it
  • Add a JUnit test that runs MessageCodeGenerator on this spec to generate component classes into a temp output directory and asserts that the generated NestedTwice.java group constructor contains:
    super(20001, 58, ORDER);
  • Optionally assert that generated file contains the ORDER array skeleton and the NoEntries group class is present (structural compile checks are covered by string contains; we don’t require javac invocation here, consistent with existing tests in this module).

Files to modify/add

  • Modify: quickfixj-codegenerator/src/main/resources/org/quickfixj/codegenerator/MessageSubclass.xsl
    • Replace the group-delimeter template for components with a version that matches any component
  • Add: quickfixj-codegenerator/src/test/resources/org/quickfixj/codegenerator/NestedComponentsTest.xml
    • Minimal dictionary as described above
  • Add: quickfixj-codegenerator/src/test/java/org/quickfixj/codegenerator/NestedComponentDelimiterTest.java
    • New JUnit test to generate classes from NestedComponentsTest.xml and assert on the generated NestedTwice.java constructor

Acceptance criteria

  • Running the new test passes on Linux/macOS/Windows JDK 8+.
  • When generating a component with a group starting with a nested component-of-component, the constructor is generated with the correct delimiter, e.g. super(20001, 58, ORDER).
  • Existing behavior for groups whose first item is a field or a group is unchanged.

Notes

  • The change is minimal and localized to the XSL template selection; it does not alter other generation templates or message/component field ordering logic.
  • The test mirrors the user-reported scenario but with a self-contained spec so CI can validate future changes.

Linked issue

This pull request was created as a result of the following prompt from Copilot chat.

Summary
Fix MessageSubclass.xsl so MessageCodeGenerator sets the group delimiter correctly when the first element of a group is a component whose first element is another component (nested > 1). Add a regression test using a minimal FIX spec to ensure the generated code uses the proper delimiter and compiles structurally.

Context

  • Repository: quickfix-j/quickfixj
  • Problem: Issue MessageCodeGenerator fails to set group delimiter for nested components #1084 reports generated code like:
    super(20001, , ORDER);
    when generating a group whose first child is a nested component-of-component. Current XSL uses a template match="group//component" in mode group-delimeter, which fails after the first recursion step (the next component node is resolved in the global /fix/components tree and no longer matches group//component). As a result, no delimiter is emitted.

Proposed changes

  1. XSLT fix (MessageSubclass.xsl)
  • Replace the component delimiter template that currently only matches descendants under a group:
    <xsl:template mode="group-delimeter" match="group//component"> ... </xsl:template>
    with a generalized version that matches any component node:
    <xsl:template mode="group-delimeter" match="component"> ... </xsl:template>
  • Keep existing field and group templates unchanged. This allows recursion across arbitrarily deep nested components to reach the first field (or nested group) and output its tag number correctly.
  1. Regression test (quickfixj-codegenerator)
  • Add a minimal FIX specification XML under test resources that defines:
    • fields: Text(58), NoEntries(20001)
    • components: Level2 contains field Text; Level1 contains component Level2; NestedTwice contains a group NoEntries whose first element is component Level1
    • a dummy message that references the NestedTwice component so code-generation includes it
  • Add a JUnit test that runs MessageCodeGenerator on this spec to generate component classes into a temp output directory and asserts that the generated NestedTwice.java group constructor contains:
    super(20001, 58, ORDER);
  • Optionally assert that generated file contains the ORDER array skeleton and the NoEntries group class is present (structural compile checks are covered by string contains; we don’t require javac invocation here, consistent with existing tests in this module).

Files to modify/add

  • Modify: quickfixj-codegenerator/src/main/resources/org/quickfixj/codegenerator/MessageSubclass.xsl
    • Replace the group-delimeter template for components with a version that matches any component
  • Add: quickfixj-codegenerator/src/test/resources/org/quickfixj/codegenerator/NestedComponentsTest.xml
    • Minimal dictionary as described above
  • Add: quickfixj-codegenerator/src/test/java/org/quickfixj/codegenerator/NestedComponentDelimiterTest.java
    • New JUnit test to generate classes from NestedComponentsTest.xml and assert on the generated NestedTwice.java constructor

Acceptance criteria

  • Running the new test passes on Linux/macOS/Windows JDK 8+.
  • When generating a component with a group starting with a nested component-of-component, the constructor is generated with the correct delimiter, e.g. super(20001, 58, ORDER).
  • Existing behavior for groups whose first item is a field or a group is unchanged.

Notes

  • The change is minimal and localized to the XSL template selection; it does not alter other generation templates or message/component field ordering logic.
  • The test mirrors the user-reported scenario but with a self-contained spec so CI can validate future changes.

Linked issue


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

- Changed MessageSubclass.xsl template from 'group//component' to 'component' in group-delimeter mode
- This allows recursion across arbitrarily deep nested components to reach the first field
- Added NestedComponentsTest.xml with minimal FIX spec for testing nested components
- Added NestedComponentDelimiterTest.java to verify correct delimiter generation
- Test confirms generated code contains 'super(20001, 58, ORDER);' for nested component groups
- All existing tests pass, no regression

Fixes #1084

Co-authored-by: chrjohn <[email protected]>
Copilot AI changed the title [WIP] Fix group delimiter in MessageSubclass.xsl for nested components Fix group delimiter generation for nested components in MessageSubclass.xsl Dec 15, 2025
Copilot AI requested a review from chrjohn December 15, 2025 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MessageCodeGenerator fails to set group delimiter for nested components

2 participants