Beispiel #1
0
        internal static object Analyze(this List <SegmentContext> segments, Separators separators, Type type, string rulesAssemblyName)
        {
            if (segments == null)
            {
                throw new ArgumentNullException("segments");
            }
            if (separators == null)
            {
                throw new ArgumentNullException("separators");
            }
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            var messageGrammar = ParseNode.BuldTree(type, true);

            if (messageGrammar.Prefix != Prefixes.M)
            {
                throw new Exception(string.Format("Only messages are supported: {0}", messageGrammar.Name));
            }

            var segmentPosition  = messageGrammar.Children.First();
            var instancePosition = new ParseNode(type);

            foreach (var segment in segments)
            {
                if (segment.IsHeader)
                {
                    continue;
                }

                Logger.Log(string.Format("Segment to match: {0}", segment.LogName));
                try
                {
                    // Jump back to HL segment if needed
                    if (segment.IsJump)
                    {
                        segmentPosition = messageGrammar.JumpToHl(instancePosition.Root(), segment.ParentId);
                    }

                    var currSeg = segmentPosition.TraverseSegmentsDepthFirst().FirstOrDefault(n => n.IsEqual(segment));
                    if (currSeg == null)
                    {
                        throw new Exception(
                                  string.Format(
                                      "Segment {0} was not found after segment {1} in class {2}.",
                                      segment.Value, segmentPosition.EdiName, type.Name));
                    }

                    var segmentTree = currSeg.AncestorsToIntersection(segmentPosition);
                    instancePosition = instancePosition.AncestorsAndSelf().Last(nt => nt.Name == segmentTree.First().Parent.Name);
                    foreach (var parseTree in segmentTree)
                    {
                        instancePosition = instancePosition.AddChild(parseTree.Type, parseTree.Type.Name);
                        if (parseTree.Prefix == Prefixes.S)
                        {
                            instancePosition.ParseSegment(segment.Value, separators);
                        }
                    }

                    segmentPosition = currSeg;
                }
                catch (Exception ex)
                {
                    throw new ParserException("Failed at line: " + segment.Value, ex);
                }
                Logger.Log(string.Format("Matched segment: {0}", segmentPosition.Name));
            }

            return(instancePosition.Root().ToInstance());
        }
        internal static void ParseSegment(this ParseNode parseNode, string line, Separators separators)
        {
            if (parseNode == null)
            {
                throw new ArgumentNullException("parseNode");
            }
            if (string.IsNullOrEmpty(line))
            {
                throw new ArgumentNullException("line");
            }
            if (separators == null)
            {
                throw new ArgumentNullException("separators");
            }

            if (parseNode.Prefix != Prefixes.S)
            {
                throw new Exception(string.Format("Only segments are supported: {0}", parseNode.Name));
            }

            var dataElementsGrammar = ParseNode.BuldTree(parseNode.Type, false).Children;
            var dataElements        = line.GetDataElements(separators);

            for (var deIndex = 0; deIndex < dataElements.Length; deIndex++)
            {
                var currentDataElement = dataElements[deIndex];
                if (string.IsNullOrEmpty(currentDataElement))
                {
                    continue;
                }
                if (dataElementsGrammar.Count <= deIndex)
                {
                    throw new ParserException(
                              string.Format(
                                  "More data elements ({0}) were found in segment {1} than in the rule class ({2}).",
                                  dataElements.Length, line, dataElementsGrammar.Count));
                }
                var currentDataElementGrammar = dataElementsGrammar.ElementAt(deIndex);

                var repetitions = currentDataElementGrammar.IsX12RepetitionSeparator()
                    ? new[] { currentDataElement }
                    : currentDataElement.GetRepetitions(separators);
                foreach (var repetition in repetitions)
                {
                    var childParseNode = parseNode.AddChild(currentDataElementGrammar.Type,
                                                            currentDataElementGrammar.Name,
                                                            currentDataElementGrammar.Prefix == Prefixes.D ? repetition.UnEscapeLine(separators) : null);

                    if (currentDataElementGrammar.Prefix != Prefixes.C)
                    {
                        continue;
                    }

                    var componentDataElementsGrammar = currentDataElementGrammar.Children;
                    var componentDataElements        = repetition.GetComponentDataElements(separators);
                    for (var cdeIndex = 0; cdeIndex < componentDataElements.Length; cdeIndex++)
                    {
                        var currentComponentDataElement = componentDataElements[cdeIndex];
                        if (string.IsNullOrEmpty(currentComponentDataElement))
                        {
                            continue;
                        }
                        if (componentDataElementsGrammar.Count <= cdeIndex)
                        {
                            throw new ParserException(
                                      string.Format("More data elements ({0}) were found in segment {1} than in the rule class {2}.",
                                                    componentDataElements.Length, currentComponentDataElement, componentDataElementsGrammar.Count));
                        }
                        var currentComponentDataElementGrammar = componentDataElementsGrammar.ElementAt(cdeIndex);

                        childParseNode.AddChild(currentComponentDataElementGrammar.Type,
                                                currentComponentDataElementGrammar.Name,
                                                currentComponentDataElement.UnEscapeLine(separators));
                    }
                }
            }
        }