Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ import quickfix.Group;</xsl:if>
</xsl:if>
</xsl:template>

<xsl:template mode="group-delimeter" match="group//component">
<xsl:template mode="group-delimeter" match="component">
<xsl:if test="position() = 1">
<xsl:variable name="name" select="@name"/>
<xsl:apply-templates select="/fix/components/component[@name=$name]/*[name(.)='field' or name(.)='group' or name(.)='component']"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.quickfixj.codegenerator;

import static org.junit.Assert.*;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;

/**
* Test for issue #1084: Verify that MessageCodeGenerator correctly sets the
* group delimiter when the first element of a group is a component whose
* first element is another component (nested > 1).
*/
public class NestedComponentDelimiterTest {

private File outputDirectory = new File("./target/test-output/nested-component-test");
private File dictFile = new File("./src/test/resources/org/quickfixj/codegenerator/NestedComponentsTest.xml");
private File schemaDirectory = new File("./src/main/resources/org/quickfixj/codegenerator");
private String fieldPackage = "quickfix.field";
private String messagePackage = "quickfix.test";
private MessageCodeGenerator generator;

@Before
public void setup() throws IOException {
if (outputDirectory.exists()) {
FileUtils.cleanDirectory(outputDirectory);
} else {
outputDirectory.mkdirs();
}
generator = new MessageCodeGenerator();
System.out.println("Successfully created an instance of the QuickFIX source generator");
}

@Test
public void testNestedComponentGroupDelimiter() throws Exception {
// Generate code from the test specification
MessageCodeGenerator.Task task = new MessageCodeGenerator.Task();
task.setName("NestedComponentsTest");
task.setSpecification(dictFile);
task.setTransformDirectory(schemaDirectory);
task.setMessagePackage(messagePackage);
task.setOutputBaseDirectory(outputDirectory);
task.setFieldPackage(fieldPackage);
task.setOverwrite(true);
task.setOrderedFields(true);
task.setDecimalGenerated(false);

generator.generate(task);

// Verify that the NestedTwice component was generated
String componentPath = outputDirectory.getAbsolutePath() + "/quickfix/test/component/NestedTwice.java";
File componentFile = new File(componentPath);
assertTrue("NestedTwice component file should exist", componentFile.exists());

// Read the generated file and check for the correct constructor
String fileContent = readFileContent(componentFile);

// Verify the NoEntries group class is present
assertTrue("NoEntries group class should be present",
fileContent.contains("public static class NoEntries extends Group"));

// Verify the ORDER array is present
assertTrue("ORDER array should be present",
fileContent.contains("private static final int[] ORDER ="));

// Verify the constructor has the correct delimiter (58 is the field number for Text)
// The constructor should be: super(20001, 58, ORDER);
assertTrue("Constructor should contain correct delimiter",
fileContent.contains("super(20001, 58, ORDER);"));

// Also verify it doesn't have an empty delimiter (the bug case)
assertFalse("Constructor should not have empty delimiter",
fileContent.contains("super(20001, , ORDER);"));
}

private String readFileContent(File file) throws FileNotFoundException {
StringBuilder content = new StringBuilder();
try (Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
content.append(scanner.nextLine()).append("\n");
}
}
return content.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<fix major="4" minor="4">
<header>
<field name="BeginString" required="Y"/>
<field name="BodyLength" required="Y"/>
<field name="MsgType" required="Y"/>
<field name="SenderCompID" required="Y"/>
<field name="TargetCompID" required="Y"/>
<field name="MsgSeqNum" required="Y"/>
<field name="SendingTime" required="Y"/>
</header>
<trailer>
<field name="CheckSum" required="Y"/>
</trailer>
<messages>
<message name="TestMessage" msgtype="TM" msgcat="app">
<component name="NestedTwice" required="N"/>
</message>
</messages>
<components>
<component name="Level2">
<field name="Text" required="N"/>
</component>
<component name="Level1">
<component name="Level2" required="N"/>
</component>
<component name="NestedTwice">
<group name="NoEntries" required="N">
<component name="Level1" required="N"/>
</group>
</component>
</components>
<fields>
<field number="8" name="BeginString" type="STRING"/>
<field number="9" name="BodyLength" type="LENGTH"/>
<field number="35" name="MsgType" type="STRING"/>
<field number="49" name="SenderCompID" type="STRING"/>
<field number="56" name="TargetCompID" type="STRING"/>
<field number="34" name="MsgSeqNum" type="SEQNUM"/>
<field number="52" name="SendingTime" type="UTCTIMESTAMP"/>
<field number="10" name="CheckSum" type="STRING"/>
<field number="58" name="Text" type="STRING"/>
<field number="20001" name="NoEntries" type="NUMINGROUP"/>
</fields>
</fix>