Skip to content

Fix generating DD from Repository #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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 @@ -32,10 +32,14 @@
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.util.JAXBSource;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
Expand Down Expand Up @@ -67,6 +71,24 @@
*/
public class DataDictionaryGenerator {

private static class UnmarshalResult {
private final Repository repository;
private final Node repositoryNode;

public UnmarshalResult(Repository repository, Node repositoryNode) {
this.repository = repository;
this.repositoryNode = repositoryNode;
}

public Repository getRepository() {
return repository;
}

public Node getRepositoryNode() {
return repositoryNode;
}
}

private static class KeyValue<T> {
final String key;
final T value;
Expand Down Expand Up @@ -112,19 +134,30 @@ public static void main(String[] args) {
private final Map<Integer, ComponentType> components = new HashMap<>();
private final Map<Integer, GroupType> groups = new HashMap<>();
private final Map<Integer, FieldType> fields = new HashMap<>();
private Document xmlDocument;
private static final String FIX_LATEST = "FIX.Latest";

public void generate(InputStream inputFile, File outputDir) throws JAXBException, IOException,
ParserConfigurationException, SAXException, XPathExpressionException {
final Repository repository = unmarshal(inputFile);
generate(repository, outputDir);
final UnmarshalResult result = unmarshal(inputFile);
generate(result.getRepository(), outputDir, result.getRepositoryNode());
}

public void generate(Repository repository, File outputDir)
throws IOException, XPathExpressionException {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Repository.class);
DOMResult domResult = new DOMResult();
TransformerFactory.newInstance().newTransformer().transform(new JAXBSource(jaxbContext, repository), domResult);
Node repositoryNode = domResult.getNode();
generate(repository, outputDir, repositoryNode);
} catch (JAXBException | TransformerException e) {
throw new RuntimeException("Failed to transform repository to document", e);
}
}

Set<Integer> requiredGroupIds = getRequiredGroups();
private void generate(Repository repository, File outputDir, Node repositoryNode)
throws IOException, XPathExpressionException {
Set<Integer> requiredGroupIds = getRequiredGroups(repositoryNode);

final List<CodeSetType> codeSetList = repository.getCodeSets().getCodeSet();
for (final CodeSetType codeSet : codeSetList) {
Expand Down Expand Up @@ -252,8 +285,9 @@ private File getSpecFilePath(File outputDir, String versionPath, String extensio
return new File(outputDir, sb.toString());
}

private Set<Integer> getRequiredGroups() throws XPathExpressionException {
private Set<Integer> getRequiredGroups(Node repositoryNode) throws XPathExpressionException {
Set<Integer> groupIds = new HashSet<>();

XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setNamespaceContext(new NamespaceContext() {

Expand All @@ -280,7 +314,7 @@ public Iterator<String> getPrefixes(String namespaceURI) {
});
String expression = "//fixr:groupRef[@presence='required']";
NodeList nodeList = (NodeList) xPath.compile(expression)
.evaluate(xmlDocument.getDocumentElement(), XPathConstants.NODESET);
.evaluate(repositoryNode, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
if (nodeList.item(i).getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) nodeList.item(i);
Expand Down Expand Up @@ -311,15 +345,16 @@ private String toConstantName(String symbolicName) {
return sb.toString().toUpperCase();
}

private Repository unmarshal(InputStream inputFile)
private UnmarshalResult unmarshal(InputStream inputFile)
throws JAXBException, ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
DocumentBuilder builder = builderFactory.newDocumentBuilder();
xmlDocument = builder.parse(inputFile);
Document document = builder.parse(inputFile);
final JAXBContext jaxbContext = JAXBContext.newInstance(Repository.class);
final Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return (Repository) jaxbUnmarshaller.unmarshal(xmlDocument);
Repository repository = (Repository) jaxbUnmarshaller.unmarshal(document);
return new UnmarshalResult(repository, document.getDocumentElement());
}

private void usage() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import io.fixprotocol._2020.orchestra.repository.Repository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

public class DataDictionaryGeneratorTest {

Expand Down Expand Up @@ -47,6 +55,27 @@ public void testGenerateFIXLatest() throws Exception {
}
}

@Test
public void testGenerateFIXLatestFromRepository(@TempDir Path tempDir) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance(Repository.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Repository repository;

try (InputStream stream = Thread.currentThread().getContextClassLoader().getResource("trade-latest.xml").openStream()) {
repository = (Repository) unmarshaller.unmarshal(stream);
}

Path outputDir = tempDir.resolve("output");
Files.createDirectory(outputDir);

generator.generate(repository, outputDir.toFile());
try (BufferedReader brTest = Files.newBufferedReader(outputDir.resolve("FIXLatest.xml"))) {
String firstLine = brTest.readLine();
assertEquals("<fix major=\"Latest\" minor=\"0\" servicepack=\"0\" extensionpack=\"269\">",
firstLine);
}
}

@Test
public void testExtract() throws Exception {
assertEquals("0", generator.extractServicePack("FIX.5.0"));
Expand Down
Loading