Exemplo n.º 1
0
        internal static object Analyze(this List <SegmentContext> segments, Separators separators,
                                       MessageContext messageContext)
        {
            if (segments == null)
            {
                throw new ArgumentNullException("segments");
            }
            if (separators == null)
            {
                throw new ArgumentNullException("separators");
            }
            if (messageContext == null)
            {
                throw new ArgumentNullException("messageContext");
            }

            var messageGrammar = ParseNode.BuldTree(messageContext.SystemType, true);

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

            var errorContext     = new MessageErrorContext(messageContext.Tag, messageContext.ControlNumber);
            var segmentPosition  = messageGrammar.Children.First();
            var instancePosition = new ParseNode(messageContext.SystemType);

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

                Logger.Log(String.Format("Segment to match: {0}", segment.LogName));
                // Jump back to HL segment if needed
                if (segment.IsJump)
                {
                    try
                    {
                        segmentPosition = messageGrammar.JumpToHl(instancePosition.Root(), segment.ParentId);
                    }
                    catch (Exception ex)
                    {
                        errorContext.Add(segment.Name, segments.IndexOf(segment) + 1, ErrorCodes.UnexpectedSegment);
                        throw new ParsingException(ErrorCodes.InvalidInterchangeContent,
                                                   "Unable to resolve HL.", ex, segment.Value, errorContext);
                    }
                }

                var currSeg = segmentPosition.TraverseSegmentsDepthFirst().FirstOrDefault(n => n.IsEqual(segment));
                if (currSeg == null)
                {
                    if (messageGrammar.Descendants().All(d => d.EdiName != segment.Name))
                    {
                        errorContext.Add(segment.Name, segments.IndexOf(segment) + 1, ErrorCodes.UnrecognizedSegment);
                        throw new ParsingException(ErrorCodes.InvalidInterchangeContent,
                                                   "Segment is not supported in rules class.", segment.Value, errorContext);
                    }

                    errorContext.Add(segment.Name, segments.IndexOf(segment) + 1, ErrorCodes.UnexpectedSegment);
                    throw new ParsingException(ErrorCodes.InvalidInterchangeContent,
                                               "Segment was not in the correct position according to the rules class.", segment.Value,
                                               errorContext);
                }

                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, errorContext);
                    }
                }
                segmentPosition = currSeg;
                Logger.Log(String.Format("Matched segment: {0}", segmentPosition.Name));
            }

            return(instancePosition.Root().ToInstance());
        }