Пример #1
0
        /// <summary>
        /// Set atribute value on a DocumentFragment based on it's xPath.
        /// If intermediate nodes are not available then this function create those nodes too.
        /// </summary>
        /// <param name="currentDocument"></param>
        /// <param name="newFragment"></param>
        public static void AddDocumentFragment(this DocumentFragment document, string xPath, string value)
        {
            if (document == null)
            {
                throw new ArgumentNullException("document");
            }

            if (string.IsNullOrEmpty(xPath))
            {
                throw new ArgumentNullException("xPath");
            }

            string attributeName = xPath.Substring(xPath.LastIndexOf(document.Pluglet.PathSeperator) + document.Pluglet.PathSeperator.Length);

            ILogger logger = LoggerFactory.Logger;

            logger.Debug("DocumentFragmentExtensions.AddDocumentFragment", "Adding attribute {0}", attributeName);

            DocumentFragment documentFragment = document.AddIntermediateDocumentFragment(xPath);

            if (documentFragment.Attributes == null)
            {
                documentFragment.Attributes = new Dictionary <string, string>();
            }
            documentFragment.Attributes.Add(attributeName, value);

            logger.Debug("DocumentFragmentExtensions.AddDocumentFragment", "Adding attribute {0}", attributeName);
        }
Пример #2
0
        /// <summary>
        /// Add new DocumentFragment based on it's xPath. If intermediate nodes are not available then this function create those nodes too.
        /// </summary>
        /// <param name="currentDocument"></param>
        /// <param name="newFragment"></param>
        public static void AddDocumentFragment(this DocumentFragment document, IDocumentFragment newFragment)
        {
            if (document == null)
            {
                throw new ArgumentNullException("document");
            }

            if (newFragment == null)
            {
                throw new ArgumentNullException("newFragment");
            }

            ILogger logger = LoggerFactory.Logger;

            logger.Debug("DocumentFragmentExtensions.AddDocumentFragment", "Adding document fragment {0}", newFragment.Name);

            DocumentFragment parentFragment = document.AddIntermediateDocumentFragment(newFragment.Pluglet.Path);

            if (parentFragment.Children == null)
            {
                parentFragment.Children = new List <IDocumentFragment>();
            }
            parentFragment.Children.Add(newFragment);
            ((DocumentFragment)newFragment).Parent = parentFragment;

            logger.Debug("DocumentFragmentExtensions.AddDocumentFragment", "Added document fragment {0}", newFragment.Name);
        }
        /// <summary>
        /// Construct DocumentFragment from IPluglet for non-leaf elements
        /// </summary>
        /// <param name="pluglet"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        public static DocumentFragment ConstructDocumentFragment(this IPluglet pluglet, IDocumentFragment parent, string value)
        {
            if (pluglet == null)
            {
                throw new ArgumentNullException("pluglet");
            }

            ++pluglet.CurrentOccurrences;

            DocumentFragment documentFragment = new DocumentFragment()
            {
                Pluglet = pluglet,
                Parent  = parent,
                Value   = value,
            };

            return(documentFragment);
        }
        /// <summary>
        /// Construct DocumentFragment for leaf node parent and then create and attach leaf nodes to it.
        /// </summary>
        /// <param name="pluglet"></param>
        /// <param name="segmentDetails"></param>
        /// <param name="internalSegment"></param>
        /// <param name="ediDelimiters"></param>
        /// <param name="segmentStartIndex"></param>
        /// <param name="segmentEndIndex"></param>
        /// <param name="ediErrors"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static DocumentFragment ConstructDocumentFragment(this IPluglet pluglet, string[] segmentDetails, bool internalSegment, Delimiters ediDelimiters,
                                                                 int segmentSeqNumber, long segmentStartIndex, long segmentEndIndex, ref InterchangeErrors ediErrors, out string error)
        {
            if (pluglet == null)
            {
                throw new ArgumentNullException("pluglet");
            }

            if (segmentDetails == null)
            {
                throw new ArgumentNullException("segmentDetails");
            }

            LoggerFactory.Logger.Info("PlugletExtensions.ConstructDocumentFragment", "Constructing {0} instance", pluglet.Tag);

            if (pluglet.Children == null)
            {
                error = string.Format("Pluglet {0} does not have childrens", pluglet.Name);
                return(null);
            }

            // -1 is required since SegmentDetails[0] is the SegmentName
            if (pluglet.Children.Count < segmentDetails.Length - 1)
            {
                error = string.Format("Document has {1} data elements, it is less than segment children count {2} as described in Spec",
                                      pluglet.Name, pluglet.Children.Count, segmentDetails.Length);
                return(null);
            }

            error = string.Empty;
            ++pluglet.CurrentOccurrences;
            DocumentFragment documentFragment = new DocumentFragment()
            {
                Pluglet        = pluglet,
                Children       = new List <IDocumentFragment>(),
                SequenceNumber = segmentSeqNumber,
                StartOffset    = segmentStartIndex,
                EndOffset      = segmentEndIndex,
            };

            int plugletNum = 0;
            DocumentFragment dataFragment;
            IPluglet         plugletChild;
            bool             validateValue;

            long currentSegmentFieldStartIndex = segmentStartIndex;

            //SegmentNum start from 1 since SegmentDetails[0] is Segment name
            int segmentNum = 1;

            // if this is internal segment (composite segment - segment handing data and segment as children) then
            // start segmentDetails from 0
            if (internalSegment == true)
            {
                segmentNum = 0;
            }

            EdiErrorType errorType = pluglet.IsIgnore ? EdiErrorType.Warning : EdiErrorType.Error;

            for (; segmentNum < segmentDetails.Length; segmentNum++, plugletNum++)
            {
                if (segmentNum != 0)
                {
                    currentSegmentFieldStartIndex += segmentDetails[segmentNum - 1].Length + 1;
                }

                validateValue = false;
                plugletChild  = pluglet.Children[plugletNum];

                if (plugletChild.PlugletType == PlugletType.Data)
                {
                    dataFragment = new DocumentFragment()
                    {
                        Parent  = documentFragment,
                        Pluglet = plugletChild,
                        Value   = segmentDetails[segmentNum],

                        /*SequenceNumber = segmentSeqNumber,
                         * StartOffset = currentSegmentFieldStartIndex,
                         * EndOffset = currentSegmentFieldStartIndex + segmentDetails[segmentNum].Length,*/
                    };

                    validateValue = true;
                }
                else if (plugletChild.PlugletType == PlugletType.Segment)
                {
                    if (string.IsNullOrEmpty(segmentDetails[segmentNum]) == false)
                    {
                        string segmentError = string.Empty;

                        string [] internalSegmentDetails = segmentDetails[segmentNum].Split((char)ediDelimiters.ComponentSeperator);

                        dataFragment = plugletChild.ConstructDocumentFragment(internalSegmentDetails, true, ediDelimiters, segmentSeqNumber, currentSegmentFieldStartIndex,
                                                                              currentSegmentFieldStartIndex + segmentDetails[segmentNum].Length, ref ediErrors, out segmentError);

                        if (string.IsNullOrEmpty(segmentError) == false)
                        {
                            if (string.IsNullOrEmpty(error) == true)
                            {
                                error = string.Format("ConstructDocumentSegmentInstance: Pluglet {0}: ", pluglet.Name);
                            }

                            error = string.Format("{0} Error constructing {1}: {2}", error, plugletChild.Name, segmentError);
                        }
                    }
                    else
                    {
                        dataFragment = new DocumentFragment()
                        {
                            Parent  = documentFragment,
                            Pluglet = plugletChild,
                            Value   = segmentDetails[segmentNum],
                        };
                    }
                }
                else
                {
                    error = string.Format("ConstructDocumentSegmentInstance: Error constructing SegmentInstance. Pluglet {0} is of type {1}",
                                          pluglet.Name, plugletChild.Name);
                    return(null);
                }

                if (validateValue == true && plugletChild.DataType != null && string.IsNullOrEmpty(segmentDetails[segmentNum]) == false)
                {
                    FieldError fieldError = plugletChild.DataType.ValidateValue(new StringBuilder(segmentDetails[segmentNum]));
                    if (fieldError != null)
                    {
                        if (string.IsNullOrEmpty(error) == true)
                        {
                            error = string.Format("ConstructDocumentSegmentInstance: Pluglet {0}: ", pluglet.Name);
                        }

                        error = string.Format("{0} Error data validation failed {1}: {2} ({3})", error, plugletChild.Name, fieldError.Description, fieldError.DataValue);

                        ediErrors.AddFieldError(segmentDetails[0], plugletChild.Tag, fieldError.ErrorCode, fieldError.Description, segmentSeqNumber, segmentNum, segmentDetails[segmentNum], currentSegmentFieldStartIndex,
                                                currentSegmentFieldStartIndex + segmentDetails[segmentNum].Length - 1, errorType);
                    }
                }

                //TODO: Add validation (extension method)
                documentFragment.Children.Add(dataFragment);

                if (string.IsNullOrEmpty(segmentDetails[segmentNum]) && plugletChild.IsMandatory == true)
                {
                    if (string.IsNullOrEmpty(error) == true)
                    {
                        error = string.Format("ConstructDocumentSegmentInstance: Pluglet {0}: ", pluglet.Name);
                    }

                    error = string.Format("{0} Child {1} is mandatory but missing", error, plugletChild.Name);

                    ediErrors.AddFieldError(segmentDetails[0], plugletChild.Tag, X12ErrorCode.DeMandatoryDataElementMissingCode,
                                            X12ErrorCode.GetDataElementErrorDescription(X12ErrorCode.DeMandatoryDataElementMissingCode), segmentSeqNumber, segmentNum, string.Empty,
                                            currentSegmentFieldStartIndex, currentSegmentFieldStartIndex, errorType);
                }
            }

            for (; segmentNum <= pluglet.Children.Count; segmentNum++, plugletNum++)
            {
                plugletChild = pluglet.Children[plugletNum];
                if (plugletChild.IsMandatory == true)
                {
                    if (string.IsNullOrEmpty(error) == true)
                    {
                        error = string.Format("ConstructDocumentSegmentInstance: Pluglet {0}: ", pluglet.Name);
                    }

                    error = string.Format("{0} Child {1} is mandatory but missing", error, plugletChild.Name);

                    ediErrors.AddFieldError(segmentDetails[0], plugletChild.Tag, X12ErrorCode.DeMandatoryDataElementMissingCode,
                                            X12ErrorCode.GetDataElementErrorDescription(X12ErrorCode.DeMandatoryDataElementMissingCode), segmentSeqNumber, segmentNum, string.Empty,
                                            currentSegmentFieldStartIndex, currentSegmentFieldStartIndex, errorType);
                }
            }

            return(documentFragment);
        }
Пример #5
0
        /// <summary>
        /// Traverse tree from DocumentFragment based on given xPath. If node is not present
        /// then add it.
        /// </summary>
        /// <param name="currentDocument"></param>
        /// <param name="xPath"></param>
        public static DocumentFragment AddIntermediateDocumentFragment(this DocumentFragment document, string xPath)
        {
            if (document == null)
            {
                throw new ArgumentNullException("document", "AddIntermediateDocumentFragment: Cannot add intermediate document fragments to null DocumentFragment");
            }

            if (string.IsNullOrEmpty(xPath))
            {
                throw new ArgumentNullException("xPath", "AddIntermediateDocumentFragment: xPath cannot be null");
            }

            ILogger logger = LoggerFactory.Logger;

            string[] pathElements = xPath.Split(new string[] { document.Pluglet.PathSeperator }, StringSplitOptions.None);

            // Check if root element and 1st element in path match
            if (string.Equals(pathElements[0], document.Name, StringComparison.OrdinalIgnoreCase) == false)
            {
                throw new PlugDataModelException(
                          string.Format("Error while adding intermediate in {0} path. First element in path {1} does not match with root element {2} of document",
                                        xPath, pathElements[0], document.Name));
            }

            DocumentFragment nextFragment    = null;
            DocumentFragment currentFragment = (DocumentFragment)document;

            StringBuilder pathTillCurrentNode = new StringBuilder();

            pathTillCurrentNode.AppendFormat("{0}", pathElements[0]);

            for (int i = 1; i < pathElements.Length - 1; i++)
            {
                //TODO: Optimize here - following call is not required once following if condition becomes true
                if (currentFragment.Children != null)
                {
                    // Check if it's last child is pathElements[i], otherwise create new instance
                    nextFragment = (DocumentFragment)currentFragment.Children.Last();

                    if (string.Equals(nextFragment.Name, pathElements[i], StringComparison.OrdinalIgnoreCase) == false)
                    {
                        nextFragment = null;
                    }

                    // Special case for last but one pathElement - Check if we need to recreate node (loop?)
                    // This is required to generate different loop nodes (e.g. BVT_X12_850.txt)
                    if (nextFragment != null && nextFragment.Children != null && i == pathElements.Length - 2 && nextFragment.Pluglet.IsRepeatable == true)
                    {
                        // Check last child and pathElements[i+1] child order
                        DocumentFragment lastChildFragment = (DocumentFragment)nextFragment.Children.Last();

                        bool restartLoop = false;
                        foreach (IPluglet child in nextFragment.Pluglet.Children)
                        {
                            if (string.Equals(child.Name, pathElements[i + 1], StringComparison.OrdinalIgnoreCase) == true)
                            {
                                restartLoop = true;
                                break;
                            }

                            if (string.Equals(child.Name, lastChildFragment.Name, StringComparison.OrdinalIgnoreCase) == true)
                            {
                                break;
                            }
                        }

                        if (restartLoop == true)
                        {
                            nextFragment = null;
                        }
                    }
                }

                pathTillCurrentNode.AppendFormat("{0}{1}", document.Pluglet.PathSeperator, pathElements[i]);
                if (nextFragment == null)
                {
                    logger.Debug("DocumentFragmentExtensions.AddDocumentFragment", "Node {0} does not exist, creating one now", currentFragment.Name);

                    IPluglet pluglet = document.Pluglet.MoveTo(pathTillCurrentNode.ToString());
                    nextFragment = pluglet.ConstructDocumentFragment(currentFragment, null);

                    if (currentFragment.Children == null)
                    {
                        currentFragment.Children = new List <IDocumentFragment>();
                    }
                    currentFragment.Children.Add(nextFragment);
                }

                currentFragment = nextFragment;
                nextFragment    = null;
            }

            return(currentFragment);
        }