public void Configure(FixValidatorSettings settings) { _settings = settings; _cachedHeader.Clear(); _cachedTrailer.Clear(); if (_settings.Dictionaries.Count > 0) { FixDictionary primary = _settings.Dictionaries[0]; // REC: Preprocess the list of elements in the primary // dictionary's header so that it doesn't have to be // done every time a message is validated: FixDxCollection hdrElements = primary.Resolve(primary.Header); foreach (IFixDxElement hdrElement in hdrElements) { _cachedHeader.Add(CreateResult(hdrElement)); } // REC: Preprocess the list of elements in the primary // dictionary's trailer so that it doesn't have to be // done every time a message is validated: FixDxCollection trlElements = primary.Resolve(primary.Trailer); foreach (IFixDxElement trlElement in trlElements) { _cachedTrailer.Add(CreateResult(trlElement)); } } }
private void PopulateMsgElements(string version, string msgType, FixMessage msg) { VfxFixVxRecord vxDetails = _vxRegistry.Get(version); if (vxDetails != null) { FixDxCollection msgElements = null; foreach (VfxFixVersion_Dictionary_Reference dxEntry in vxDetails.Dictionaries) { // REC: Retrieve the dictionary associated with // the version definition: FixDictionary dxInstance = _dxRegistry.GetEntry(dxEntry.Name); // REC: Attempt to retrieve the specified message // type from the dictionary: FixDxMessage dxMessage = dxInstance.GetMessageByType(msgType); if (dxMessage != null) { msgElements = dxInstance.Resolve(dxMessage.Elements); break; } } if (msgElements != null) { // REC: Create the sort ordering for the elements // and populate any fields and groups that have been // registered with the assembler: Collection <int> ordering = new Collection <int>(); foreach (IFixDxElement dxElement in msgElements) { ordering.Add(dxElement.Tag); if (dxElement is FixDxResolvedField) { if (_mapFields.ContainsKey(dxElement.Tag)) { msg.Content.SetField(_mapFields[dxElement.Tag]); } } else { if (_mapGroups.ContainsKey(dxElement.Tag)) { msg.Content.AddGroup(_mapGroups[dxElement.Tag]); } } } // REC: Assign the sort ordering for the header // elements to the message's header: msg.Content.SetOrdering(ordering); } } }
/// <summary> /// The GetUniqueMessages method retrieves a collection which /// represents the set of all FIX message definitions found in /// the dictionaries associated with a specific version. /// </summary> /// <param name="version"> /// The name of the version definition that is to be used /// for looking up the FIX message definitions. /// </param> /// <returns> /// The collection of message definitions that represents /// the complete set of all of the field definitions in the /// dictionaries associated with the specified version. /// </returns> public FixDxCollection GetUniqueMessages(string version) { FixDxCollection result = new FixDxCollection(); if (_vxRegistry != null) { VfxFixVxRecord vxDetails = _vxRegistry.Get(version); if (vxDetails != null) { if (_dxRegistry != null) { // REC: Temporary map that is used to ensure there // is only one instance of each MsgType: Dictionary <string, FixDxMessage> mapMessages = new Dictionary <string, FixDxMessage>(); // REC: Iterate over all of the FIX dictionaries that // are associated with the version and build the list // of FIX field definitions from them: foreach (VfxFixVersion_Dictionary_Reference dxEntry in vxDetails.Dictionaries) { FixDictionary dxInstance = _dxRegistry.GetEntry(dxEntry.Name); if (dxInstance != null) { foreach (IFixDxElement dxElement in dxInstance.Messages) { FixDxMessage dxMessage = dxElement as FixDxMessage; if (dxMessage != null) { if (mapMessages.ContainsKey(dxMessage.MsgType) == false) { mapMessages.Add(dxMessage.MsgType, dxMessage); } else { mapMessages[dxMessage.MsgType] = dxMessage; } } } } } foreach (string key in mapMessages.Keys) { result.Add(mapMessages[key]); } } } } return(result); }
/// <summary> /// The GetUniqueFields method retrieves a collection which /// represents the set of all FIX field definitions found in /// the dictionaries associated with a specific version. /// </summary> /// <param name="version"> /// The name of the version definition that is to be used /// for looking up the FIX field definitions. /// </param> /// <returns> /// The collection of FIX field definitions that represents /// the complete set of all of the field definitions in the /// dictionaries associated with the specified version. /// </returns> public FixDxCollection GetUniqueFields(string version) { FixDxCollection result = new FixDxCollection(); if (_vxRegistry != null) { VfxFixVxRecord vxDetails = _vxRegistry.Get(version); if (vxDetails != null) { if (_dxRegistry != null) { // REC: Temporary map that is used to ensure there // is only one instance of a field for each tag. Dictionary <int, FixDxField> mapFields = new Dictionary <int, FixDxField>(); // REC: Iterate over all of the FIX dictionaries that // are associated with the version and build the list // of FIX field definitions from them: foreach (VfxFixVersion_Dictionary_Reference dxEntry in vxDetails.Dictionaries) { FixDictionary dxInstance = _dxRegistry.GetEntry(dxEntry.Name); if (dxInstance != null) { foreach (IFixDxElement dxElement in dxInstance.Fields) { FixDxField dxField = dxElement as FixDxField; if (dxField != null) { if (mapFields.ContainsKey(dxField.Tag) == false) { mapFields.Add(dxField.Tag, dxField); } else { mapFields[dxField.Tag] = dxField; } } } } } foreach (int key in mapFields.Keys) { result.Add(mapFields[key]); } } } } return(result); }
private void PopulateTrlElements(string version, FixMessage msg) { VfxFixVxRecord vxDetails = _vxRegistry.Get(version); if (vxDetails != null) { // REC: Ensure that there is at least one FIX dictionary // assigned to the specified version definition: if (vxDetails.Dictionaries.Count > 0) { FixDictionary dxEntry = _dxRegistry.GetEntry(vxDetails.Dictionaries[0].Name); if (dxEntry != null) { FixDxCollection trlElements = dxEntry.Resolve(dxEntry.Trailer); if (trlElements != null) { // REC: Create the sort ordering for the elements // and populate any fields and groups that have been // registered with the assembler: Collection <int> ordering = new Collection <int>(); foreach (IFixDxElement dxElement in trlElements) { ordering.Add(dxElement.Tag); if (dxElement is FixDxResolvedField) { if (_mapFields.ContainsKey(dxElement.Tag)) { msg.Trailer.SetField(_mapFields[dxElement.Tag]); } } else { if (_mapGroups.ContainsKey(dxElement.Tag)) { msg.Trailer.AddGroup(_mapGroups[dxElement.Tag]); } } } // REC: Assign the sort ordering for the header // elements to the message's header: msg.Trailer.SetOrdering(ordering); } } else { string error = string.Format("Dictionary \"{0}\" not registered.", vxDetails.Dictionaries[0]); throw new ArgumentException(error); } } else { string error = string.Format("The version \"{0}\" has no associated dictionaries.", version); throw new ArgumentException(error); } } else { string error = string.Format("The version \"{0}\" is not registered.", version); throw new ArgumentException(error); } }
// REC: Validate an instance of the FixMessage class against // the header/message/trailer definition in the dictionaries: public List <FixValidationResult> Validate(FixMessage msg) { List <FixValidationResult> result = new List <FixValidationResult>(); // REC: Build a queue of all of the FIX elements that // are contained in the message: Queue <SrcField> srcFields = new Queue <SrcField>(); // REC: Add the elements that are in the message's // header to the queue of source fields: PopulateQueue(srcFields, msg.Header); // REC: Add the elements that are in the message's // body to the queue of source fields: PopulateQueue(srcFields, msg.Content); // REC: Add the elements that are in the message's // trailer to the queue of source fields: PopulateQueue(srcFields, msg.Trailer); // REC: Create the MsgLayout structure that defines // the layout of a message as it is defined in the // configured FIX dictionaries: MsgLayout msgLayout = new MsgLayout(); // REC: The message layout's header entries are // copied from the cached list of entries that is // created when the validator is configured: foreach (FixValidationResult hdrEntry in _cachedHeader) { msgLayout.Header.Add(hdrEntry.Clone() as FixValidationResult); } // REC: The message layout's content entries are // only configured if the corresponding message // type can be found in the dictionaries: FixField fldMsgType = msg.Header.GetField(35); if (fldMsgType != null) { string strMsgType = fldMsgType.Content; foreach (FixDictionary dx in _settings.Dictionaries) { FixDxMessage dxMessage = dx.GetMessageByType(strMsgType); if (dxMessage != null) { // REC: Expand the list of elements contained // in the message's definition and populate the // message layout element list with them: FixDxCollection msgElements = dx.Resolve(dxMessage.Elements); foreach (IFixDxElement msgElement in msgElements) { msgLayout.Message.Add(CreateResult(msgElement)); } break; } } } // REC: the message layout's trailer entries are // copied from the cached list of entries that is // created when the validator is configured: foreach (FixValidationResult trlEntry in _cachedTrailer) { msgLayout.Trailer.Add(trlEntry.Clone() as FixValidationResult); } // REC: After the message layout has been defined // the validator can compare the content of the // source message to the layout definition: return(ProcessElements(srcFields, msgLayout)); }
/// <summary> /// The Resolve method attempts to resolve all of the /// element references in a collection to the entries /// that correspond to them. /// </summary> /// <param name="elements"> /// The collection of dictionary elements to resolve. /// </param> /// <returns> /// The resulting collection of resolved elements. /// </returns> /// <exception cref="ArgumentException"> /// Thrown if any elements in the collection that is /// supplied to the method cannot be resolved. /// </exception> public FixDxCollection Resolve(FixDxCollection elements) { FixDxCollection result = new FixDxCollection(); // REC: Iterate over all of the elements in the collection // and determine how to resolve each of them: foreach (IFixDxElement dxElement in elements) { if (dxElement is FixDxFieldReference) { FixDxFieldReference fieldReference = dxElement as FixDxFieldReference; result.Add(ResolveFieldReference(fieldReference)); } else if (dxElement is FixDxGroupReference) { FixDxGroupReference groupReference = dxElement as FixDxGroupReference; result.Add(ResolveGroupReference(groupReference)); } else if (dxElement is FixDxBlockReference) { FixDxBlockReference blockReference = dxElement as FixDxBlockReference; // REC: Determine what type of block the reference // is referring to (component or repeating): if (string.IsNullOrEmpty(blockReference.Name)) { string error = "The supplied block reference's name is null or empty."; throw new ArgumentException(error); } else if (!_mapBlocksByName.ContainsKey(blockReference.Name)) { string error = string.Format("The block reference {0} couldn't be resolved.", blockReference.Name); throw new ArgumentException(error); } else { FixDxBlock dxBlock = _mapBlocksByName[blockReference.Name]; if (dxBlock.Type == FixDxBlockTypes.Component) { foreach (IFixDxElement element in Resolve(Expand(dxBlock.Elements))) { result.Add(element); } } else if (dxBlock.Type == FixDxBlockTypes.Repeating) { // REC: Attempt to resolve the field that the repeating // block references as the start field for the group: if (string.IsNullOrEmpty(dxBlock.Field)) { string error = string.Format("Repeating Block {0}'s start field is null or empty.", dxBlock.Field); throw new ArgumentException(error); } else if (!_mapFieldsByName.ContainsKey(dxBlock.Field)) { string error = string.Format("Repeating block {0}'s start field can't be resolved.", dxBlock.Field); throw new ArgumentException(error); } else { FixDxField dxField = _mapFieldsByName[dxBlock.Field]; FixDxResolvedGroup dxGroup = new FixDxResolvedGroup(dxField.Tag, dxField.Name, false); foreach (IFixDxElement element in Resolve(Expand(dxBlock.Elements))) { dxGroup.Elements.Add(element); } result.Add(dxGroup); } } } } } // REC: Patch from RC - sanity check all elements in the result // to ensure that there are no unresolved references. foreach (IFixDxElement e in result) { if (e is FixDxFieldReference || e is FixDxGroupReference || e is FixDxFieldReference) { throw new Exception("unresolved references exist in the resolved collection"); } } return result; }
/// <summary> /// The Expand method iterates over all of the elements in /// a collection of dictionary elements and expands any of /// them that reference collections of other elements. /// </summary> /// <param name="source"> /// The collection of elements to expand. /// </param> /// <returns> /// A new instance of a collection of dictionary elements /// with all expandable references in the source collection /// having been recursively expanded. /// </returns> public FixDxCollection Expand(FixDxCollection source) { FixDxCollection result = new FixDxCollection(); foreach (IFixDxElement dxEntry in source) { if (dxEntry is FixDxBlockReference) { FixDxBlockReference blockReference = dxEntry as FixDxBlockReference; if (blockReference != null) { if (_mapBlocksByName.ContainsKey(blockReference.Name)) { FixDxBlock blockEntry = _mapBlocksByName[blockReference.Name]; FixDxCollection blockElements = Expand(blockEntry.Elements); foreach (IFixDxElement blockElement in blockElements) { if (blockElement is FixDxFieldReference) { FixDxFieldReference reference = blockElement as FixDxFieldReference; result.Add(reference); } else if (blockElement is FixDxBlockReference) { FixDxBlockReference reference = blockElement as FixDxBlockReference; result.Add(reference); } } } } } else { if (dxEntry is FixDxGroupReference) { FixDxGroupReference srcReference = dxEntry as FixDxGroupReference; FixDxGroupReference dstReference = new FixDxGroupReference(srcReference.Name, srcReference.Required); foreach (IFixDxElement srcElement in Expand(srcReference.Elements)) { dstReference.Elements.Add(srcElement); } result.Add(dstReference); } else if (dxEntry is FixDxFieldReference) { FixDxFieldReference element = dxEntry as FixDxFieldReference; result.Add(element); } } } return result; }
/// <summary> /// The TranslateElements method iterates over a list of objects /// from an entity in the XML representation of a dictionary and /// translates them into a collection of VFX dictionary types. /// </summary> /// <param name="elements"> /// The list of objects from an entity in the XML representation /// of a VersaFix dictionary. /// </param> /// <returns> /// An instance of FixDxCollection that has been populated with /// the VersaFix dictionary types that correspond to the objects /// in the list of XML elements. /// </returns> private static FixDxCollection TranslateElements(List<object> elements) { FixDxCollection result = new FixDxCollection(); foreach (object element in elements) { if (element is XmlFixDxFieldReference) { XmlFixDxFieldReference src = element as XmlFixDxFieldReference; result.Add(new FixDxFieldReference(src.Name, src.Required)); } else if (element is XmlFixDxGroupReference) { XmlFixDxGroupReference src = element as XmlFixDxGroupReference; FixDxGroupReference dst = new FixDxGroupReference(src.Name, src.Required); foreach (IFixDxElement member in TranslateElements(src.Elements)) { dst.Elements.Add(member); } result.Add(dst); } else if(element is XmlFixDxBlockReference) { XmlFixDxBlockReference src = element as XmlFixDxBlockReference; result.Add(new FixDxBlockReference(src.Name, src.Required)); } } return result; }
/// <summary> /// The TranslateElements method converts a collection of /// dictionary elements into their corresponding representation /// as instances of XML serializable classes. The method only /// translates field, group, and block references, since those /// are the only elements that should be found in collections /// of dictionary elements under normal usage. /// </summary> /// <param name="dxElements"> /// The collection of field, group, and block references that /// is to be converted to XML serializable classes. /// </param> /// <returns> /// The resulting collection of XML serializable classes. /// </returns> private static XmlFixDxElements TranslateElements(FixDxCollection dxElements) { XmlFixDxElements result = new XmlFixDxElements(); foreach (IFixDxElement dxElement in dxElements) { if (dxElement is FixDxFieldReference) { FixDxFieldReference dxReference = dxElement as FixDxFieldReference; XmlFixDxFieldReference xmlReference = new XmlFixDxFieldReference(); xmlReference.Name = dxReference.Name; xmlReference.Required = dxReference.Required; result.Elements.Add(xmlReference); } else if (dxElement is FixDxGroupReference) { FixDxGroupReference dxReference = dxElement as FixDxGroupReference; XmlFixDxGroupReference xmlReference = new XmlFixDxGroupReference(); xmlReference.Name = dxReference.Name; xmlReference.Required = dxReference.Required; XmlFixDxElements xmlElements = TranslateElements(dxReference.Elements); foreach (object xmlElement in xmlElements.Elements) { xmlReference.Elements.Add(xmlElement); } result.Elements.Add(xmlReference); } else if (dxElement is FixDxBlockReference) { FixDxBlockReference dxReference = dxElement as FixDxBlockReference; XmlFixDxBlockReference xmlReference = new XmlFixDxBlockReference(); xmlReference.Name = dxReference.Name; xmlReference.Required = dxReference.Required; result.Elements.Add(xmlReference); } } return result; }
/// <summary> /// The GetUniqueMessages method retrieves a collection which /// represents the set of all FIX message definitions found in /// the dictionaries associated with a specific version. /// </summary> /// <param name="version"> /// The name of the version definition that is to be used /// for looking up the FIX message definitions. /// </param> /// <returns> /// The collection of message definitions that represents /// the complete set of all of the field definitions in the /// dictionaries associated with the specified version. /// </returns> public FixDxCollection GetUniqueMessages(string version) { FixDxCollection result = new FixDxCollection(); if (_vxRegistry != null) { VfxFixVxRecord vxDetails = _vxRegistry.Get(version); if (vxDetails != null) { if (_dxRegistry != null) { // REC: Temporary map that is used to ensure there // is only one instance of each MsgType: Dictionary<string, FixDxMessage> mapMessages = new Dictionary<string, FixDxMessage>(); // REC: Iterate over all of the FIX dictionaries that // are associated with the version and build the list // of FIX field definitions from them: foreach (VfxFixVersion_Dictionary_Reference dxEntry in vxDetails.Dictionaries) { FixDictionary dxInstance = _dxRegistry.GetEntry(dxEntry.Name); if (dxInstance != null) { foreach (IFixDxElement dxElement in dxInstance.Messages) { FixDxMessage dxMessage = dxElement as FixDxMessage; if (dxMessage != null) { if (mapMessages.ContainsKey(dxMessage.MsgType) == false) { mapMessages.Add(dxMessage.MsgType, dxMessage); } else { mapMessages[dxMessage.MsgType] = dxMessage; } } } } } foreach (string key in mapMessages.Keys) { result.Add(mapMessages[key]); } } } } return result; }
/// <summary> /// The GetUniqueFields method retrieves a collection which /// represents the set of all FIX field definitions found in /// the dictionaries associated with a specific version. /// </summary> /// <param name="version"> /// The name of the version definition that is to be used /// for looking up the FIX field definitions. /// </param> /// <returns> /// The collection of FIX field definitions that represents /// the complete set of all of the field definitions in the /// dictionaries associated with the specified version. /// </returns> public FixDxCollection GetUniqueFields(string version) { FixDxCollection result = new FixDxCollection(); if (_vxRegistry != null) { VfxFixVxRecord vxDetails = _vxRegistry.Get(version); if (vxDetails != null) { if (_dxRegistry != null) { // REC: Temporary map that is used to ensure there // is only one instance of a field for each tag. Dictionary<int, FixDxField> mapFields = new Dictionary<int, FixDxField>(); // REC: Iterate over all of the FIX dictionaries that // are associated with the version and build the list // of FIX field definitions from them: foreach (VfxFixVersion_Dictionary_Reference dxEntry in vxDetails.Dictionaries) { FixDictionary dxInstance = _dxRegistry.GetEntry(dxEntry.Name); if (dxInstance != null) { foreach (IFixDxElement dxElement in dxInstance.Fields) { FixDxField dxField = dxElement as FixDxField; if (dxField != null) { if (mapFields.ContainsKey(dxField.Tag) == false) { mapFields.Add(dxField.Tag, dxField); } else { mapFields[dxField.Tag] = dxField; } } } } } foreach (int key in mapFields.Keys) { result.Add(mapFields[key]); } } } } return result; }