org.quickfixj.dictgenerator.Generator Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) quickfixengine.org All rights reserved.
*
* This file is part of the QuickFIX FIX Engine
*
* This file may be distributed under the terms of the quickfixengine.org
* license as defined by quickfixengine.org and appearing in the file
* LICENSE included in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* See http://www.quickfixengine.org/LICENSE for licensing information.
*
* Contact [email protected] if any conditions of this licensing
* are not clear to you.
******************************************************************************/
package org.quickfixj.dictgenerator;
import java.io.BufferedWriter;
import java.io.File;
import java.io.Writer;
import java.util.*;
/**
* QFJ-483: QFJ Dictionary Generator
* Credit for the initial version goes to Morten Kristiansen.
* There were some changes made regarding ordering of tags etc, in order to make the
* dictionaries look more similar to the existing QFJ dictionaries.
*
* NB: Do not forget to correct the major/minor number in the session data dictionary afterwards.
*
* This generator only works with the FPL 2008/09 repository files (http://fixprotocol.org/repository-2008).
*/
public class Generator {
private final Repository repository;
private final int major;
private final int minor;
public Generator(File repositoryDir, int major, int minor) throws Exception {
System.out.println("Building Repository: " + repositoryDir.getAbsolutePath() + "...");
this.repository = new Repository(repositoryDir);
this.major = major;
this.minor = minor;
}
public void generate() throws Exception {
generateDictionary("session.xml", true, false);
generateDictionary("application.xml", false, false);
generateDictionary("merged.xml", false, true); // for versions below FIX5.0
}
private void generateDictionary(String file, boolean admin, boolean merged) {
File dictionaryFile = new File(file);
System.out.println("Creating file: " + dictionaryFile.getAbsolutePath());
StringBuilder builder = new StringBuilder();
if (!merged) {
if (admin) {
builder.append("\n");
} else {
builder.append("\n");
}
} else {
builder.append("\n");
}
Map msgTypes = new LinkedHashMap<>();
if (!merged) {
if (admin) {
msgTypes.putAll(repository.getSessionMsgTypes());
} else {
msgTypes.putAll(repository.getApplicationMsgTypes());
}
} else {
msgTypes.putAll(repository.getSessionMsgTypes());
msgTypes.putAll(repository.getApplicationMsgTypes());
}
Set fieldsUsed = getAllFieldsUsed(msgTypes);
Set componentsUsed = getAllComponentsUsed(msgTypes);
// Header
if (!merged) {
if (admin) {
builder.append(" \n");
Component standardHeader = repository.getStandardHeader(getNextMsgType(msgTypes));
addMsgContents(builder, standardHeader.getMsgContent(), " ");
builder.append(" \n");
builder.append(" \n");
Component standardTrailer = repository.getStandardTrailer(getNextMsgType(msgTypes));
addMsgContents(builder, standardTrailer.getMsgContent(), " ");
builder.append(" \n");
} else {
builder.append(" \n");
builder.append(" \n");
}
} else {
builder.append(" \n");
Component standardHeader = repository.getStandardHeader(getNextMsgType(msgTypes));
addMsgContents(builder, standardHeader.getMsgContent(), " ");
builder.append(" \n");
builder.append(" \n");
Component standardTrailer = repository.getStandardTrailer(getNextMsgType(msgTypes));
addMsgContents(builder, standardTrailer.getMsgContent(), " ");
builder.append(" \n");
}
// Message
if (!merged) {
String msgcat = admin ? "admin" : "app";
builder.append(" \n");
for (MsgType msgType : msgTypes.values()) {
if (msgType.getMsgType().equals("n")) {
builder.append(" \n");
}
}
builder.append(" \n");
} else {
builder.append(" \n");
for (MsgType msgType : msgTypes.values()) {
String msgcat = msgType.getCategory().equals("Session") ? "admin" : "app";
if (msgType.getMsgType().equals("n")) {
builder.append(" \n");
}
}
builder.append(" \n");
}
// Components
builder.append(" \n");
Map components = repository.getComponents();
for (String name : componentsUsed) {
Component component = components.get(name);
builder.append(" \n");
Field numInGroup = null;
for (Object o : component.getMsgContent()) {
if (o instanceof Field && ((Field) o).isNumInGroup()) {
numInGroup = (Field) o;
break;
}
}
if (numInGroup != null) {
builder.append(" \n");
addMsgContents(builder, component.getMsgContent(), " ");
builder.append(" \n");
} else {
addMsgContents(builder, component.getMsgContent(), " ");
}
builder.append(" \n");
}
builder.append(" \n");
// Fields
builder.append(" \n");
Map fields = repository.getFields();
for (Integer tagInt : fieldsUsed) {
String tag = String.valueOf(tagInt);
Field field = fields.get(tag);
String fieldType = field.getType();
builder.append(" \n");
Set enumDescCache = new HashSet<>();
for (Enum theEnum : field.getEnums()) {
String enumDesc = theEnum.getDesc().toUpperCase();
enumDesc = enumDesc.replaceAll("\\(.*\\)", ""); // remove stuff in parentheses
enumDesc = enumDesc.replaceAll("'", ""); // replace ticks (as in DON'T_KNOW_TRADE)
enumDesc = enumDesc.replaceAll("\"", "");
enumDesc = enumDesc.trim(); // trim leading and trailing whitespaces
enumDesc = enumDesc.replaceAll("\\W+", "_"); // replace rest of non-word characters by _
char firstChar = enumDesc.charAt(0);
if (Character.isDigit(firstChar)) {
enumDesc = "_" + enumDesc; // make it a valid JAVA identifier
}
boolean add = enumDescCache.add(enumDesc);
if (add) {
builder.append(" \n");
} else {
// FIXME ugly workaround to avoid duplicate entries
enumDesc = enumDesc + "_1";
enumDescCache.add(enumDesc);
builder.append(" \n");
}
}
builder.append(" \n");
} else {
builder.append("/>\n");
}
}
builder.append(" \n");
builder.append(" ");
try {
Writer writer = new BufferedWriter(new java.io.FileWriter(dictionaryFile));
writer.write(builder.toString());
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private MsgType getNextMsgType(Map msgTypes) {
Iterator it = msgTypes.values().iterator();
if(it.hasNext()) {
return it.next();
} else {
throw new RuntimeException("Message type not found. Check the MsgType.xml file.");
}
}
private void addMsgContents(StringBuilder builder, List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy