package quickfix.dictgenerator; import java.io.File; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.dom4j.Document; import org.dom4j.Node; import org.dom4j.io.SAXReader; public class Repository { private final File repository; private final Document components, enums, fields, msgContents, msgType; private final Map<String, MsgType> sessionMsgTypes = new TreeMap<String, MsgType>(), applicationMsgTypes = new TreeMap<String, MsgType>(); private final Map<String, Field> allFields = new TreeMap<String, Field>(); private final Map<String, Component> allComponents = new TreeMap<String, Component>(); public Repository(File repositoryFile) throws Exception { this.repository = repositoryFile; Set<String> requiredFiles = new HashSet<String>(); requiredFiles.add("Components.xml"); requiredFiles.add("Enums.xml"); requiredFiles.add("Fields.xml"); requiredFiles.add("MsgContents.xml"); requiredFiles.add("MsgType.xml"); for (File file : repository.listFiles()) { if (requiredFiles.contains(file.getName())) { requiredFiles.remove(file.getName()); } } if (!requiredFiles.isEmpty()) { throw new Exception("Invalid repository: Missing required files: " + requiredFiles); } SAXReader reader = new SAXReader(); components = reader.read(new File(repository, "Components.xml")); enums = reader.read(new File(repository, "Enums.xml")); fields = reader.read(new File(repository, "Fields.xml")); msgContents = reader.read(new File(repository, "MsgContents.xml")); msgType = reader.read(new File(repository, "MsgType.xml")); initFields(); initComponents(); initMsgTypes(sessionMsgTypes, "1"); initMsgTypes(applicationMsgTypes, "0"); } public final Map<String, MsgType> getSessionMsgTypes() { return sessionMsgTypes; } public final Component getStandardHeader(MsgType msgType) { for (Object o : msgType.getMsgContent()) { if (o instanceof Component && ((Component)o).isStandardHeader()) { return (Component) o; } } return null; } public final Component getStandardTrailer(MsgType msgType) { for (Object o : msgType.getMsgContent()) { if (o instanceof Component && ((Component)o).isStandardTrailer()) { return (Component) o; } } return null; } public final Map<String, MsgType> getApplicationMsgTypes() { return applicationMsgTypes; } public final Map<String, Field> getFields() { return allFields; } public final Map<String, Component> getComponents() { return allComponents; } private void initMsgTypes(Map<String, MsgType> msgTypeMap, String notReqXML) { System.out.println(getClass().getSimpleName() + ": Init MsgTypes (" + notReqXML + ")..."); List<?> msgTypeNodes = msgType.selectNodes("//dataroot/MsgType[NotReqXML=" + notReqXML + "]"); for (Object o : msgTypeNodes) { Node node = (Node) o; String msgID = node.selectSingleNode("MsgID").getText(); String messageName = node.selectSingleNode("MessageName").getText(); String componentType = node.selectSingleNode("ComponentType").getText(); String category = node.selectSingleNode("Category").getText(); String msgType = node.selectSingleNode("MsgType").getText(); msgTypeMap.put(msgType, new MsgType(msgID, messageName, componentType, category, notReqXML, msgType)); } System.out.println(getClass().getSimpleName() + ": " + msgTypeMap.size() + " MsgTypes found"); // Add msgContents for (MsgType msgType : msgTypeMap.values()) { List<?> msgContentsNodes = getMsgContents(msgType.getMsgID()); System.out.println("\t " + msgType.getName()); for (Object o : msgContentsNodes) { Node node = (Node) o; String tagText = node.selectSingleNode("TagText").getText(); String reqd = node.selectSingleNode("Reqd").getText(); //if (allFields.containsKey(tagText) && notReqXML.equals(allFields.get(tagText).getNotReqXML())) { if (allFields.containsKey(tagText)) { MsgTypeField msgTypeField = new MsgTypeField(allFields.get(tagText), reqd); msgType.addMsgContent(msgTypeField); System.out.println("\t\t " + allFields.get(tagText).getFieldName()); //} else if (allComponents.containsKey(tagText) && notReqXML.equals(allComponents.get(tagText).getNotReqXML())) { } else if (allComponents.containsKey(tagText)) { MsgTypeComponent msgTypeComponent = new MsgTypeComponent(allComponents.get(tagText), reqd); msgType.addMsgContent(msgTypeComponent); System.out.println("\t\t " + allComponents.get(tagText).getName()); } else { System.err.println("Could not find tagText: " + tagText); } } } } private void initFields() { System.out.println(getClass().getSimpleName() + ": Init Fields..."); List<?> fieldNodes = fields.selectNodes("//dataroot/Fields"); for (Object o : fieldNodes) { Node node = (Node) o; String tag = node.selectSingleNode("Tag").getText(); String fieldName = node.selectSingleNode("FieldName").getText(); System.out.println("\t " + fieldName + "(" + tag + ")"); String type = node.selectSingleNode("Type").getText(); String desc = node.selectSingleNode("Desc").getText(); String notReqXML = node.selectSingleNode("NotReqXML").getText(); Field field = new Field(tag, fieldName, type, desc, notReqXML); allFields.put(field.getTag(), field); // Find enums List<?> enumNodes = enums.selectNodes("//dataroot/Enums[Tag=" + tag + "]"); Collections.sort(enumNodes, new EnumNodeComparator()); if (enumNodes != null && !enumNodes.isEmpty()) { for (Object enumO : enumNodes) { Node enumNode = (Node) enumO; String enumName = enumNode.selectSingleNode("Enum").getText(); System.out.println("\t\t " + enumName); String enumDesc = enumNode.selectSingleNode("Description").getText(); field.addEnum(new Enum(enumName, enumDesc)); } } } System.out.println(getClass().getSimpleName() + ": " + allFields.size() + " Fields found"); } private void initComponents() { System.out.println(getClass().getSimpleName() + ": Init Components..."); List<?> componentNodes = components.selectNodes("//dataroot/Components"); for (Object o : componentNodes) { Node node = (Node) o; String msgID = node.selectSingleNode("MsgID").getText(); String componentName = node.selectSingleNode("ComponentName").getText(); String componentType = node.selectSingleNode("ComponentType").getText(); String category = node.selectSingleNode("Category").getText(); String notReqXML = node.selectSingleNode("NotReqXML").getText(); allComponents.put(componentName, new Component(msgID, componentName, componentType, category, notReqXML)); } System.out.println(getClass().getSimpleName() + ": " + allComponents.size() + " Components found"); // Add msgContents for (Component component : allComponents.values()) { addComponentMsgContent(component, "\t"); } } private void addComponentMsgContent(Component component, String prefix) { List<?> msgContentsNodes = getMsgContents(component.getMsgID()); System.out.println(prefix + " " + component.getName()); if (!component.getMsgContent().isEmpty()) { System.out.println(prefix + "\talready handled, return"); return; } for (Object o : msgContentsNodes) { Node node = (Node) o; String tagText = node.selectSingleNode("TagText").getText(); String reqd = node.selectSingleNode("Reqd").getText(); if (allFields.containsKey(tagText)) { ComponentField componentField = new ComponentField(allFields.get(tagText), reqd); component.addMsgContent(componentField); System.out.println(prefix + "\t " + allFields.get(tagText).getFieldName()); } else if (allComponents.containsKey(tagText)) { // Handle msgContents for the component in question first! addComponentMsgContent(allComponents.get(tagText), prefix + "\t"); ComponentComponent componentComponent = new ComponentComponent(allComponents.get(tagText), reqd); component.addMsgContent(componentComponent); System.out.println(prefix + "\t " + allComponents.get(tagText).getName()); } else { System.err.println("Could not find tagText: " + tagText); } } } private List<?> getMsgContents(String msgID) { List<?> nodes = msgContents.selectNodes("//dataroot/MsgContents[MsgID=" + msgID + "]"); Collections.sort(nodes, new MsgContentNodeComparator()); return nodes; } class MsgContentNodeComparator implements Comparator<Object> { public int compare(Object o1, Object o2) { try { Double pos1 = Double.parseDouble(((Node)o1).selectSingleNode("Position").getText()); Double pos2 = Double.parseDouble(((Node)o2).selectSingleNode("Position").getText()); return pos1.compareTo(pos2); } catch (Exception e) { return 0; } } } class EnumNodeComparator implements Comparator<Object> { public int compare(Object o1, Object o2) { try { Double pos1 = Double.parseDouble(((Node)o1).selectSingleNode("Sort").getText()); Double pos2 = Double.parseDouble(((Node)o2).selectSingleNode("Sort").getText()); return pos1.compareTo(pos2); } catch (Exception e) { return 0; } } } }