/// <summary> /// The CloneBlock method is invoked to create a copy of an /// instance of a component block definition. /// </summary> /// <param name="source"> /// The component block to be duplicated. /// </param> /// <returns> /// The resulting clone of the supplied block. /// </returns> private FixDxBlock CloneBlock(FixDxBlock source) { FixDxBlock result = new FixDxBlock(source.Name, source.Category, source.Field); foreach (IFixDxElement dxElement in source.Elements) { result.Elements.Add(CloneElement(dxElement)); } return(result); }
/// <summary> /// The GetBlockByName method attempts to lookup a block /// based on the text name that is assigned to it. /// </summary> /// <param name="name"> /// The name of the component block to retrieve. /// </param> /// <returns> /// The corresponding component block, or null if there is /// no matching entry in the dictionary. /// </returns> public FixDxBlock GetBlockByName(string name) { FixDxBlock result = null; if (_mapBlocksByName.ContainsKey(name)) { result = _mapBlocksByName[name]; } 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 AddBlock method adds an instance of a FIX component /// block to the dictionary. If there is already an instance /// of a component block with the same name, an operation is /// not allowed and an ArgumentException is thrown. /// </summary> /// <param name="dxBlock"> /// The FIX component block definition that is to be added. /// </param> public void AddBlock(FixDxBlock dxBlock) { if (_mapBlocksByName.ContainsKey(dxBlock.Name)) { string error = string.Format("Dictionary already contains a block named {0}.", dxBlock.Name); throw new ArgumentException(error); } _mapBlocksByName.Add(dxBlock.Name, dxBlock); _blkElements.Add(dxBlock); }
/// <summary> /// The PopulateBlocks method populates the blocks section /// of the supplied VFX dictionary with all of the blocks /// that are defined in the supplied XML dictionary. /// </summary> /// <param name="source"> /// The source dictionary for the block elements. /// </param> /// <param name="target"> /// The target dictionary for the converted elements. /// </param> private static void PopulateBlocks(XmlDictionary source, FixDictionary target) { foreach (XmlFixDxBlock src in source.Blocks.Entries) { FixDxBlock dst = new FixDxBlock(src.Name); dst.Type = (FixDxBlockTypes)Enum.Parse(typeof(FixDxBlockTypes), src.Type); dst.Field = src.Field; dst.Category = src.Category; foreach (IFixDxElement element in TranslateElements(src.Elements)) { dst.Elements.Add(element); } target.AddBlock(dst); } }
/// <summary> /// The ExportBlocks method is invoked to convert all of /// the block elements in an instance of a VersaFix data /// dictionary into corresponding entries in an instance /// of an XML representation of a QuickFix dictionary. /// </summary> /// <param name="src"> /// The source dictionary for the block definitions. /// </param> /// <param name="dst"> /// The target dictionary for the block definitions. /// </param> private void ExportBlocks(FixDictionary src, XmlQfxDictionary dst) { foreach (IFixDxElement dxElement in src.Blocks) { FixDxBlock dxBlock = dxElement as FixDxBlock; if (dxBlock != null) { XmlQfxBlock xmlBlock = new XmlQfxBlock(); xmlBlock.Name = dxBlock.Name; foreach (IFixDxElement dxBlockElement in dxBlock.Elements) { ExportElement(dxBlockElement, xmlBlock.Elements); } dst.Blocks.Add(xmlBlock); } } }
/// <summary> /// The PopulateBlocks method is invoked to convert all of the /// component block definitions in a QuickFix dictionary into /// corresponding component block definitions in an instance of /// a VersaFix dictionary. /// </summary> /// <param name="src"> /// The QuickFix dictionary to copy the blocks from. /// </param> /// <param name="dst"> /// The VersaFix dictionary to copy the blocks into. /// </param> private void PopulateBlocks(XmlQfxDictionary src, FixDictionary dst) { foreach (object block in src.Blocks) { XmlQfxBlock xmlBlock = block as XmlQfxBlock; if (xmlBlock != null) { if (!string.IsNullOrEmpty(xmlBlock.Name)) { FixDxBlock dxBlock = new FixDxBlock(xmlBlock.Name); foreach (object element in xmlBlock.Elements) { IFixDxElement dxElement = ConvertElement(element); if (dxElement != null) { dxBlock.Elements.Add(dxElement); } } dst.Blocks.Add(dxBlock); } } } }
/// <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); }