Skip to content

Commit 6208839

Browse files
authored
Merge pull request #1097 from quickfix-j/copilot/fix-group-delimiter-issue
Fix group delimiter resolution for nested components in XSL template
2 parents f9b1929 + 1251aa9 commit 6208839

3 files changed

Lines changed: 133 additions & 1 deletion

File tree

quickfixj-codegenerator/src/main/resources/org/quickfixj/codegenerator/MessageSubclass.xsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ import quickfix.Group;</xsl:if>
197197
</xsl:if>
198198
</xsl:template>
199199

200-
<xsl:template mode="group-delimeter" match="group//component">
200+
<xsl:template mode="group-delimeter" match="component">
201201
<xsl:if test="position() = 1">
202202
<xsl:variable name="name" select="@name"/>
203203
<xsl:apply-templates select="/fix/components/component[@name=$name]/*[name(.)='field' or name(.)='group' or name(.)='component']"
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package org.quickfixj.codegenerator;
2+
3+
import static org.junit.Assert.*;
4+
5+
import java.io.File;
6+
import java.io.FileNotFoundException;
7+
import java.io.IOException;
8+
import java.util.Scanner;
9+
10+
import org.junit.Before;
11+
import org.junit.Rule;
12+
import org.junit.Test;
13+
import org.junit.rules.TemporaryFolder;
14+
15+
/**
16+
* Test for issue #1084: Verify that MessageCodeGenerator correctly sets the
17+
* group delimiter when the first element of a group is a component whose
18+
* first element is another component (nested > 1).
19+
*/
20+
public class NestedComponentDelimiterTest {
21+
22+
@Rule
23+
public TemporaryFolder tempFolder = new TemporaryFolder();
24+
25+
private File dictFile = new File("./src/test/resources/org/quickfixj/codegenerator/NestedComponentsTest.xml");
26+
private File schemaDirectory = new File("./src/main/resources/org/quickfixj/codegenerator");
27+
private String fieldPackage = "quickfix.field";
28+
private String messagePackage = "quickfix.test";
29+
private MessageCodeGenerator generator;
30+
31+
@Before
32+
public void setup() throws IOException {
33+
generator = new MessageCodeGenerator();
34+
}
35+
36+
@Test
37+
public void testNestedComponentGroupDelimiter() throws Exception {
38+
// Generate code from the test specification
39+
MessageCodeGenerator.Task task = new MessageCodeGenerator.Task();
40+
task.setName("NestedComponentsTest");
41+
task.setSpecification(dictFile);
42+
task.setTransformDirectory(schemaDirectory);
43+
task.setMessagePackage(messagePackage);
44+
task.setOutputBaseDirectory(tempFolder.getRoot());
45+
task.setFieldPackage(fieldPackage);
46+
task.setOverwrite(true);
47+
task.setOrderedFields(true);
48+
task.setDecimalGenerated(false);
49+
50+
generator.generate(task);
51+
52+
// Verify that the NestedTwice component was generated
53+
String componentPath = tempFolder.getRoot().getAbsolutePath() + "/quickfix/test/component/NestedTwice.java";
54+
File componentFile = new File(componentPath);
55+
assertTrue("NestedTwice component file should exist", componentFile.exists());
56+
57+
// Read the generated file and check for the correct constructor
58+
String fileContent = readFileContent(componentFile);
59+
60+
// Verify the NoEntries group class is present
61+
assertTrue("NoEntries group class should be present",
62+
fileContent.contains("public static class NoEntries extends Group"));
63+
64+
// Verify the ORDER array is present
65+
assertTrue("ORDER array should be present",
66+
fileContent.contains("private static final int[] ORDER ="));
67+
68+
// Verify the constructor has the correct delimiter (58 is the field number for Text)
69+
// The constructor should be: super(20001, 58, ORDER);
70+
assertTrue("Constructor should contain correct delimiter",
71+
fileContent.contains("super(20001, 58, ORDER);"));
72+
73+
// Also verify it doesn't have an empty delimiter (the bug case)
74+
assertFalse("Constructor should not have empty delimiter",
75+
fileContent.contains("super(20001, , ORDER);"));
76+
}
77+
78+
private String readFileContent(File file) throws FileNotFoundException {
79+
StringBuilder content = new StringBuilder();
80+
try (Scanner scanner = new Scanner(file)) {
81+
while (scanner.hasNextLine()) {
82+
content.append(scanner.nextLine()).append("\n");
83+
}
84+
}
85+
return content.toString();
86+
}
87+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<fix major="4" minor="4">
3+
<header>
4+
<field name="BeginString" required="Y"/>
5+
<field name="BodyLength" required="Y"/>
6+
<field name="MsgType" required="Y"/>
7+
<field name="SenderCompID" required="Y"/>
8+
<field name="TargetCompID" required="Y"/>
9+
<field name="MsgSeqNum" required="Y"/>
10+
<field name="SendingTime" required="Y"/>
11+
</header>
12+
<trailer>
13+
<field name="CheckSum" required="Y"/>
14+
</trailer>
15+
<messages>
16+
<message name="TestMessage" msgtype="TM" msgcat="app">
17+
<component name="NestedTwice" required="N"/>
18+
</message>
19+
</messages>
20+
<components>
21+
<component name="Level2">
22+
<field name="Text" required="N"/>
23+
</component>
24+
<component name="Level1">
25+
<component name="Level2" required="N"/>
26+
</component>
27+
<component name="NestedTwice">
28+
<group name="NoEntries" required="N">
29+
<component name="Level1" required="N"/>
30+
</group>
31+
</component>
32+
</components>
33+
<fields>
34+
<field number="8" name="BeginString" type="STRING"/>
35+
<field number="9" name="BodyLength" type="LENGTH"/>
36+
<field number="35" name="MsgType" type="STRING"/>
37+
<field number="49" name="SenderCompID" type="STRING"/>
38+
<field number="56" name="TargetCompID" type="STRING"/>
39+
<field number="34" name="MsgSeqNum" type="SEQNUM"/>
40+
<field number="52" name="SendingTime" type="UTCTIMESTAMP"/>
41+
<field number="10" name="CheckSum" type="STRING"/>
42+
<field number="58" name="Text" type="STRING"/>
43+
<field number="20001" name="NoEntries" type="NUMINGROUP"/>
44+
</fields>
45+
</fix>

0 commit comments

Comments
 (0)