protected override DocumentPlug ConstructDocumentPlug(ExcelWorksheet schemaWorksheet, int startRow) { Pluglet rootPluglet = new Pluglet("X12", "GC root Node", PlugletType.Loop, null, 1, -1); DocumentPlug documentPlug = new DocumentPlug(rootPluglet, BusinessDomain.FlatFile); ReadMetadata(documentPlug, schemaWorksheet); string currentLoopName = string.Empty; string nextLoopName; IPluglet loopPluglet = null; IPluglet nextPluglet; int minOccurs, maxOccurs; int row = startRow; while ((nextPluglet = GetSegment(schemaWorksheet, ref row, out nextLoopName)) != null) { // In case of flat file, we do not have loops rootPluglet.Children.Add(nextPluglet); nextPluglet.Parent = rootPluglet; } return(documentPlug); }
protected static void FillInMissingChildren(IPluglet segment) { IList <IPluglet> inputList = segment.Children; int origLength = inputList.Count; if (origLength < 2) { return; } int visitIndex = 0; string prefix; int expectedNumber = GetSequenceNumber(inputList[0].Name, out prefix); int visitedNodeNumber; int numberOfNodesVisited = 0; while (numberOfNodesVisited < origLength) { visitedNodeNumber = GetSequenceNumber(inputList[visitIndex].Name, out prefix); numberOfNodesVisited++; //initialize the sequence if (visitedNodeNumber >= 0 && expectedNumber < 0) { expectedNumber = visitedNodeNumber; } //if a gap in sequence space is found if (visitedNodeNumber > expectedNumber) { //fill in the range of numbers from expectedNumber to (visitedNodeNumber-1) for (int fillCount = 0; fillCount <= visitedNodeNumber - 1 - expectedNumber; fillCount++) { string newNodeName = GenerateName(prefix, expectedNumber + fillCount); //more formally consturct a new node here using appropriate constructor IPluglet child = new Pluglet(newNodeName, newNodeName, PlugletType.Data, null, 0, 1, true); child.DataType = new X12_AnDataType("AN", -1, -1); inputList.Insert(visitIndex + fillCount, child); child.Parent = segment; } visitIndex += visitedNodeNumber - expectedNumber + 1; expectedNumber = visitedNodeNumber + 1; } else { visitIndex++; if (expectedNumber >= 0) { expectedNumber++; } } } }
private void createPluglet(string name, string description, PlugletType type, IPluglet parent, string mandatory, string repeatable) { int maxOccurs = 1; int minOccurs = 1; if (repeatable.Equals("Y")) { maxOccurs = -1; } if (mandatory == "N") { minOccurs = 0; } //if (type == PlugletType.Loop) // maxOccurs = -1; Pluglet pluglet = new Pluglet(name, description, type, parent, minOccurs, maxOccurs); }
protected override DocumentPlug ConstructDocumentPlug(ExcelWorksheet schemaWorksheet, int startRow) { ReadMetadata(schemaWorksheet); Pluglet rootPluglet = new Pluglet( new PlugletInput() { Name = RootNodeName, Definition = "GC root node", Type = PlugletType.Loop, Parent = null, IsTagSameAsName = true, // for XML spec cert tag is always same as name }); DocumentPlug documentPlug = new DocumentPlug(rootPluglet, BusinessDomain.Xml); // Assumption: Element names are not repeated on teh subsequent lines IPluglet loopPluglet = null; IPluglet nextPluglet; int minOccurs, maxOccurs; int row = startRow; // This loop is for level-1 nodes try { while ((nextPluglet = GetNextNode(schemaWorksheet, 1, ref row)) != null) { rootPluglet.Children.Add(nextPluglet); nextPluglet.Parent = rootPluglet; } } catch (Exception ex) { throw new Exception(string.Format("Row: {0}, Error: {1}", row, ex.Message)); } return(documentPlug); }
public void createRootPluglet(Stream stream, string type) { //path = Path.Combine(RepositoryRoot, @"sources\test\PlugTestHarness\output\Copy of Inbound850ToSuperspecPlug.xlsx"); //fileInfo = new FileInfo(path); using (ExcelPackage pck = new ExcelPackage(stream)) { ExcelWorkbook workBook = pck.Workbook; //change worksheet index here for source or target if (type.Equals("Source#")) { current = workBook.Worksheets[1]; } else { current = workBook.Worksheets[2]; } rootPluglet = new Pluglet(retreiveRootName(type), "root Node", (PlugletType)Enum.Parse(typeof(PlugletType), "Segment"), null); int rowCount = current.Dimension.End.Row - current.Dimension.Start.Row + 2; for (int row = 2; row < rowCount; row++) { if (current.Cells[row, NodeTypeIndex].Value == null) { continue; } string name = extractName(row); createPluglet(name, current.Cells[row, DescriptionIndex].Value.ToString(), (PlugletType)Enum.Parse(typeof(PlugletType), current.Cells[row, NodeTypeIndex].Value.ToString()), retreiveParent(current.Cells[row, PathIndex].Value.ToString()), current.Cells[row, MandatoryIndex].Value.ToString(), current.Cells[row, RepeatableIndex].Value.ToString()); } } }
private IPluglet GetSegment(ExcelWorksheet schemaWorksheet, ref int row, out string nextLoopName) { nextLoopName = null; // TODO: Handle this in better way if (row > schemaWorksheet.Dimension.End.Row) { return(null); } // Currently setting Min and Max for segment is hard coded as 0, 1, since these values are not present in excel int segmentMinOccur = 0; int segmentMaxOccur = 100; // First read Segment row FlatFileSchemaRow segmentRow = ReadRow(schemaWorksheet, row) as FlatFileSchemaRow; while (segmentRow != null && string.IsNullOrWhiteSpace(segmentRow.Segment) == true) { row++; segmentRow = ReadRow(schemaWorksheet, row) as FlatFileSchemaRow; } if (segmentRow == null) { return(null); } nextLoopName = segmentRow.Loop; segmentMinOccur = string.Compare(segmentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0; segmentMaxOccur = string.Compare(segmentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1000; IPluglet segment = new Pluglet(segmentRow.Segment, segmentRow.DataElementTag, (PlugletType)Enum.Parse(typeof(PlugletType), "Segment"), null , segmentMinOccur, segmentMaxOccur); if (string.IsNullOrWhiteSpace(segmentRow.Loop) == false) { segment.Name = segmentRow.Loop; } ++row; IPluglet dataPluglet = null; int minOccurs, maxOccurs; bool isIgnore; int tempRow; // Now read all data elements till groupping column has some value (indicates new Segment started) while ((segmentRow = ReadRow(schemaWorksheet, row) as FlatFileSchemaRow) != null) { if (string.IsNullOrEmpty(segmentRow.Segment) == false) { break; } // TODO: What about mandatory flag value 'X'? minOccurs = string.Compare(segmentRow.MandatoryCode, "M", true) == 0 && string.Compare(segmentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0; maxOccurs = string.Compare(segmentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1; isIgnore = string.Compare(segmentRow.IgnoreFlag, "I", true) == 0; dataPluglet = new Pluglet(segmentRow.DataElementTag, segmentRow.DataElementName, (PlugletType)Enum.Parse(typeof(PlugletType), "Data"), segment, minOccurs, maxOccurs, isIgnore); ++row; dataPluglet.DataType = ReadDataType(segmentRow, schemaWorksheet, segment.Path, ref row); } FillInMissingChildren(segment); return(segment); }
private IPluglet GetNextNode(ExcelWorksheet schemaWorksheet, int currentLevel, ref int row) { // TODO: Handle this in better way if (row > schemaWorksheet.Dimension.End.Row) { return(null); } // Currently setting Min and Max for segment is hard coded as 0, 100, since these values are not present in excel int segmentMinOccur = 0; int segmentMaxOccur = 100; int loopMinOccur = 0; int loopMaxOccur = 100; XmlFileSchemaRow currentRow = ReadRow(schemaWorksheet, row) as XmlFileSchemaRow; XmlFileSchemaRow nextRow = ReadRow(schemaWorksheet, row + 1) as XmlFileSchemaRow; IPluglet nextNode = null; IPluglet childNode = null; if (nextRow.IsLeafNode) { segmentMinOccur = string.Compare(currentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0; segmentMaxOccur = string.Compare(currentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1000; // If next row contains leaf node then we need to construct segment nextNode = new Pluglet( new PlugletInput() { Name = currentRow.ElementName, Definition = currentRow.ElementName, Type = PlugletType.Segment, Parent = null, MinOccurs = segmentMinOccur, MaxOccurs = segmentMaxOccur, IsTagSameAsName = true, // for XML spec cert tag is always same as name }); IPluglet dataPluglet = null; // Now read all data elements currentRow = nextRow; ++row; while (currentRow != null && currentRow.Level == currentLevel + 1) { if (currentRow.IsLeafNode) { ++row; int minOccurs, maxOccurs; bool isIgnore; // TODO: What about mandatory flag value 'X'? minOccurs = string.Compare(currentRow.MandatoryCode, "M", true) == 0 && string.Compare(currentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0; maxOccurs = string.Compare(currentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1; isIgnore = string.Compare(currentRow.IgnoreFlag, "I", true) == 0; dataPluglet = new Pluglet( new PlugletInput() { Name = currentRow.ElementName, Definition = currentRow.ElementName, Type = PlugletType.Data, Parent = nextNode, MinOccurs = minOccurs, MaxOccurs = maxOccurs, IsIgnore = isIgnore, IsTagSameAsName = true, // for XML spec cert tag is always same as name }); dataPluglet.DataType = ReadDataType(currentRow, schemaWorksheet, nextNode.Path, ref row); } else { childNode = GetNextNode(schemaWorksheet, currentLevel + 1, ref row); nextNode.Children.Add(childNode); childNode.Parent = nextNode; } currentRow = ReadRow(schemaWorksheet, row) as XmlFileSchemaRow; } } else { // If next row contains non-leaf node then we need to construct loop element nextNode = new Pluglet( new PlugletInput() { Name = currentRow.ElementName, Definition = currentRow.ElementName, Type = PlugletType.Loop, Parent = null, MinOccurs = loopMinOccur, MaxOccurs = loopMaxOccur, IsTagSameAsName = true, // for XML spec cert tag is always same as name }); ++row; // Read all child elements (level is > current level) while (nextRow != null && nextRow.Level > currentLevel) { childNode = GetNextNode(schemaWorksheet, currentLevel + 1, ref row); nextNode.Children.Add(childNode); childNode.Parent = nextNode; nextRow = ReadRow(schemaWorksheet, row) as XmlFileSchemaRow; } } // Do we need this for xml cert files? // FillInMissingChildren(segment); return(nextNode); }
private List <string> GetAllPresentValues(List <IDocumentFragment> documentFragments, Pluglet pluglet) { List <string> presentValues = new List <string>(); foreach (DocumentFragment documentfragment in documentFragments) { foreach (DocumentFragment child in documentfragment.Children) { if (string.Compare(child.Pluglet.Tag, pluglet.Tag, true) == 0) { presentValues.Add(child.Value); break; } } } return(presentValues); }
/// <summary> /// Find corrosponding Pluglet for given segmentname and create new segment /// </summary> /// <param name="segmentName"></param> /// <param name="segmentDetails"></param> private void CreateAndAddNewSegment(string segmentName, string[] segmentDetails) { const string firstSegmentName = "ST"; string errorMsgs = string.Empty; IPluglet nextPluglet; string location = "EDIReader.CreateAndAddNewSegment"; Logger.Debug(location, "Adding {0} segment", segmentName); string missingMandatorySegments; nextPluglet = CurrentPluglet.GetSegmentPluglet(segmentName, segmentDetails, firstSegmentName, out missingMandatorySegments); // First add missing mandatory segment errors if (nextPluglet != null && !string.IsNullOrWhiteSpace(missingMandatorySegments)) { string error = string.Format("Missing mandatory segments ({0}) between {1} and {2}" , missingMandatorySegments, CurrentPluglet.Tag, segmentName); if (FatpipeDocumentInst.Errors == null) { FatpipeDocumentInst.Errors = new List <string>(); } FatpipeDocumentInst.Errors.Add(error); Logger.Error("EDIReader.CreateAndAddNewSegment", EventId.EDIReaderMissingMandatorySegment, "{0} - {1}", GetCurrentPosContext(), error); EdiErrorType errorType = nextPluglet.IsIgnore ? EdiErrorType.Warning : EdiErrorType.Error; foreach (string segment in missingMandatorySegments.Split(',')) { Errors.AddSegmentError(segmentName, X12ErrorCode.MandatorySegmentMissingCode , string.Format("{0} : {1}", X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.MandatorySegmentMissingCode), segment) , SegmentNumber, this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, errorType); } } if (nextPluglet == null) { /* //TODO: Revisit following if condition - do we really want to ignore ISA/GS segment missing in schema? * if (segmentName != "ISA" && segmentName != "GS") * { * errors = string.Format("{0} segment not found in schema after {1}", segmentName, CurrentPluglet.Name); * * Logger.Error(location, EventId.EDIReaderUnknownSegment, "{0} - {1}", GetCurrentPosContext(), errors); * Errors.AddSegmentError(segmentName, X12ErrorCode.UnrecognizedSegmentIDCode * , X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.UnrecognizedSegmentIDCode), SegmentNumber); * } */ //experimenting with unknown here above is actual //IPluglet unknown = new Pluglet("UNRECOGNIZED_SEGMENT", "Unknown Segment", PlugletType.Segment, CurrentPluglet.Parent); IPluglet unknown = new Pluglet( new PlugletInput() { Name = "UNRECOGNIZED_SEGMENT", Definition = "Unknown Segment", Type = PlugletType.Segment, Parent = CurrentPluglet.Parent, IsIgnore = false, AddToParent = false, IsTagSameAsName = true, }); // IPluglet x = new Pluglet("child"+i, "Unknown Data", PlugletType.Data, unknown); //unknown.Children.Add(x); //} //DocumentFragment newFragment = unknown.ConstructDocumentFragment(segmentDetails, false, EDIDelimiters, out errors); errorMsgs = string.Format("{0} segment not found in schema after {1}", segmentName, CurrentPluglet.Name); Errors.AddSegmentError(segmentName, X12ErrorCode.UnrecognizedSegmentIDCode , X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.UnrecognizedSegmentIDCode), SegmentNumber , this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, EdiErrorType.Error); DocumentFragment newFragment = new DocumentFragment() { Pluglet = unknown, Children = new List <IDocumentFragment>(), }; IPluglet childPluglet = new Pluglet("Data", "Data", PlugletType.Data, null); DocumentFragment child = new DocumentFragment() { Parent = newFragment, Pluglet = childPluglet, Children = null, SequenceNumber = SegmentNumber, StartOffset = this.CurrentSegmentStartPos, EndOffset = this.CurrentSegmentEndPos - 1, }; newFragment.Children.Add(child); child.Value = CurrentSegment; if (newFragment == null) { errorMsgs = string.Format("{0} DocumentFragment creation failed. Errors: {1}", segmentName, errorMsgs); Logger.Error(location, EventId.EDIReaderDocFragmentCreation, "{0} - {1}", GetCurrentPosContext(), errorMsgs); //TODO: what should be the code here? //Errors.AddGenericError(segmentName, X12ErrorCode.??? } else { ((DocumentFragment)FatpipeDocumentInst.RootFragment).AddDocumentFragment(newFragment); // CurrentPluglet = newFragment.Pluglet; } //experimenting with unknown here } else { if (nextPluglet.RepetitionInfo.MaxOccurs == 0) { Errors.AddSegmentError(segmentName, X12ErrorCode.UnexpectedSegmentCode , string.Format("{0} : {1}", X12ErrorCode.GetStandardSegmentErrorDescription(X12ErrorCode.UnexpectedSegmentCode), nextPluglet.Tag) , SegmentNumber, this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, EdiErrorType.Error); } else { DocumentFragment newFragment = nextPluglet.ConstructDocumentFragment(segmentDetails, false, EDIDelimiters, SegmentNumber, this.CurrentSegmentStartPos, this.CurrentSegmentEndPos - 1, ref errors, out errorMsgs); if (newFragment == null) { //errorMsgs = string.Format("{0} DocumentFragment creation failed. Errors: {1}", segmentName, errorMsgs); Logger.Error(location, EventId.EDIReaderDocFragmentCreation, "{0} - {1}", GetCurrentPosContext(), errorMsgs); // TODO: Replace UnexpectedSegmentCode with appropriate one Errors.AddGenericError(segmentName, X12ErrorCode.UnexpectedSegmentCode, errorMsgs, SegmentNumber, this.CurrentSegmentStartPos, this.CurrentSegmentEndPos); } else { ((DocumentFragment)FatpipeDocumentInst.RootFragment).AddDocumentFragment(newFragment); CurrentPluglet = newFragment.Pluglet; } } } if (!string.IsNullOrEmpty(errorMsgs)) { if (FatpipeDocumentInst.Errors == null) { FatpipeDocumentInst.Errors = new List <string>(); } FatpipeDocumentInst.Errors.Add(errorMsgs); } }
private IPluglet GetSegment(ExcelWorksheet schemaWorksheet, ref int row, out string nextLoopName) { // TODO: Handle this in better way if (row > schemaWorksheet.Dimension.End.Row) { nextLoopName = null; return(null); } // Currently setting Min and Max for segment is hard coded as 0, 1, since these values are not present in excel int segmentMinOccur = 0; int segmentMaxOccur = 100; bool isIgnore; // First read Segment row X12SchemaRow segmentRow = ReadRow(schemaWorksheet, row) as X12SchemaRow; nextLoopName = segmentRow.Loop; if (nextLoopName == null) { nextLoopName = string.Empty; } segmentMinOccur = string.Compare(segmentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0; segmentMaxOccur = string.Compare(segmentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1000; isIgnore = string.Compare(segmentRow.IgnoreFlag, "I", true) == 0; IPluglet segment = new Pluglet(segmentRow.Segment, segmentRow.DataElementTag, PlugletType.Segment, null, segmentMinOccur, segmentMaxOccur, isIgnore); string xPath = nextLoopName; if (string.Compare(xPath, "n/a", true) == 0) { xPath = nextLoopName = string.Empty; } if (string.IsNullOrWhiteSpace(xPath) == false) { xPath = string.Format("X12{0}{1}Loop{2}{3}{4}", segment.PathSeperator, xPath, segment.PathSeperator, segment.Tag, segment.PathSeperator); } else { xPath = string.Format("X12{0}{1}{2}", segment.PathSeperator, segment.Tag, segment.PathSeperator); } ++row; IPluglet dataPluglet = null; int minOccurs, maxOccurs; // Now read all data elements till groupping column has some value (indicates new Segment started) while ((segmentRow = ReadRow(schemaWorksheet, row) as X12SchemaRow) != null) { if (string.IsNullOrEmpty(segmentRow.Grouping) == false) { break; } // TODO: What about mandatory flag value 'X'? minOccurs = string.Compare(segmentRow.MandatoryCode, "M", true) == 0 && string.Compare(segmentRow.MandatoryFlag, "Y", true) == 0 ? 1 : 0; maxOccurs = string.Compare(segmentRow.MandatoryFlag, "N", true) == 0 ? 0 : 1; isIgnore = string.Compare(segmentRow.IgnoreFlag, "I", true) == 0; dataPluglet = new Pluglet( new PlugletInput() { Name = segmentRow.DataElementTag, Definition = segmentRow.DataElementName, Type = PlugletType.Data, Parent = segment, MinOccurs = minOccurs, MaxOccurs = maxOccurs, IsIgnore = isIgnore, IsTriggerField = segmentRow.IsTriggerField }); ++row; dataPluglet.DataType = ReadDataType(segmentRow, schemaWorksheet, string.Format("{0}{1}", xPath, segmentRow.DataElementTag), ref row); } FillInMissingChildren(segment); return(segment); }
protected override DocumentPlug ConstructDocumentPlug(ExcelWorksheet schemaWorksheet, int startRow) { Pluglet rootPluglet = new Pluglet("X12", "GC root Node", PlugletType.Loop, null, 1, -1); DocumentPlug documentPlug = new DocumentPlug(rootPluglet, BusinessDomain.X12); if (string.IsNullOrWhiteSpace(schemaWorksheet.Name) == false) { int documentType; string strDocumentType = schemaWorksheet.Name.Substring(0, schemaWorksheet.Name.IndexOf(" ")); if (int.TryParse(strDocumentType, out documentType) == true) { documentPlug.DocumentType = documentType; } } string currentLoopName = string.Empty; string nextLoopName; string loopName; List <string> intermediateLoops = new List <string>(); IPluglet loopPluglet = null; IPluglet nextPluglet; IPluglet loopParent; int minOccurs, maxOccurs; int row = startRow; int current, next; loopPluglet = rootPluglet; while ((nextPluglet = GetSegment(schemaWorksheet, ref row, out nextLoopName)) != null) { // In case of flat file, we do not have loops if (string.IsNullOrEmpty(nextLoopName)) { rootPluglet.Children.Add(nextPluglet); nextPluglet.Parent = rootPluglet; loopPluglet = rootPluglet; intermediateLoops.Clear(); currentLoopName = nextLoopName; } else { // Check if at least one intermediate loop name is different in next loop if (string.Compare(currentLoopName, nextLoopName) != 0) { loopName = nextLoopName; string[] nextLoops = nextLoopName.Split(new string[] { "->" }, StringSplitOptions.None); // Find first non-matching loop name between intermediateLoops and nextLoops current = next = 0; while (current < intermediateLoops.Count && next < nextLoops.Length) { if (string.Equals(intermediateLoops[current], nextLoops[next], StringComparison.OrdinalIgnoreCase) == false) { break; } current++; next++; } // Get loopParent from current intermediate loops for (int i = intermediateLoops.Count - 1; i >= current; i--) { loopPluglet = loopPluglet.Parent; } loopParent = loopPluglet; // Remove all non-matching intermediate loops int loopsCount = intermediateLoops.Count; for (int i = current; i < loopsCount; i++) { intermediateLoops.RemoveAt(current); } // Add new intermediate loops for (int j = next; j < nextLoops.Length; j++) { // TODO: Any criteria for setting min and max occurs for loop? minOccurs = 1; maxOccurs = 100; // create new loop loopPluglet = new Pluglet(nextLoops[j] + "Loop", "Loop Node", PlugletType.Loop, loopParent, minOccurs, maxOccurs); intermediateLoops.Add(nextLoops[j]); loopParent = loopPluglet; } currentLoopName = nextLoopName; } loopPluglet.Children.Add(nextPluglet); nextPluglet.Parent = loopPluglet; } } return(documentPlug); }