예제 #1
0
 public QueryPathQueuePredicate(IQueryPathOperand left)
 {
     this.Left     = left;
     this.Operator = XPathOperator.Unknown;
 }
예제 #2
0
 public QueryPathQueuePredicate(IQueryPathOperand left, XPathOperator op, IQueryPathOperand right)
 {
     this.Left     = left;
     this.Operator = op;
     this.Right    = right;
 }
예제 #3
0
        public QueryPathQueue(QueryPathAttribute queryPath, IBase baseObject)
        {
            var currentObject = baseObject;
            var expression    = queryPath.XPathExpression;
            var partQueue     = new Queue <IXPathPart>(queryPath.PartQueue);
            QueryPathQueueItem currentQueueItem = null;

            this.Items          = new Queue <QueryPathQueueItem>();
            this.LoadParentPath = queryPath;
            this.BaseObject     = baseObject;
            this.QueryPathKind  = queryPath.QueryPathKind;

            while (partQueue.Count > 0)
            {
                var part = partQueue.Dequeue();

                if (part is XPathElement element)
                {
                    var parentObject = (IParentBase)currentObject;
                    var childObject  = parentObject.ChildNodes.SingleOrDefault(n => n.Name == element.Text);

                    if (childObject == null)
                    {
                        if (parentObject is NavigationProperty)
                        {
                            childObject = parentObject.ChildNodes.Single();

                            if (this.QueryPathKind == QueryKind.LoadParentReference && partQueue.Count == 0)
                            {
                                currentQueueItem.AssumeSingleOperator = true;
                            }

                            currentQueueItem = new QueryPathQueueItem(childObject);
                            this.Items.Enqueue(currentQueueItem);

                            parentObject = (IParentBase)childObject;

                            childObject = parentObject.ChildNodes.SingleOrDefault(n => n.Name == element.Text);
                        }
                    }

                    currentQueueItem = new QueryPathQueueItem(childObject);
                    this.Items.Enqueue(currentQueueItem);

                    currentObject = childObject;
                    parentObject  = (IParentBase)currentObject;

                    if (element.Predicates != null && element.Predicates.Count > 0)
                    {
                        QueryPathQueueItem dequeuedItem = null;

                        foreach (var predicate in element.Predicates)
                        {
                            var left = predicate.Left;
                            var op   = predicate.Operator;
                            IQueryPathOperand       queueLeft  = null;
                            IQueryPathOperand       queueRight = null;
                            QueryPathQueuePredicate queuePredicate;

                            if (left is XPathAttribute xpathAttribute)
                            {
                                var parentSetElement = (IElement)parentObject.ChildNodes.Single();
                                var attribute        = (IAttribute)parentSetElement.Attributes.Single(n => n.Name == xpathAttribute.Name);
                                var queueAttribute   = new QueryPathQueueAttribute(attribute);
                                var nextPart         = partQueue.Peek();

                                if (nextPart is XPathElement xpathElement)
                                {
                                    if (xpathElement.Text == parentSetElement.Name)
                                    {
                                        part         = partQueue.Dequeue();
                                        dequeuedItem = new QueryPathQueueItem(parentSetElement);
                                    }

                                    currentObject = parentSetElement;
                                }

                                queueLeft = queueAttribute;
                            }
                            else
                            {
                                DebugUtils.Break();
                            }

                            if (op != CodePlex.XPathParser.XPathOperator.Unknown)
                            {
                                var right = predicate.Right;

                                if (right is XPathFunction pathFunction)
                                {
                                    var kind          = EnumUtils.GetValue <QueryPathFunctionKind>(pathFunction.Name);
                                    var args          = pathFunction.Args;
                                    var queueFunction = new QueryPathQueueFunction(kind, args);

                                    queueRight = queueFunction;
                                }
                                else
                                {
                                    DebugUtils.Break();
                                }
                            }

                            queuePredicate = new QueryPathQueuePredicate(queueLeft, op, queueRight);
                            currentQueueItem.Predicates.Add(queuePredicate);

                            if (dequeuedItem != null)
                            {
                                currentQueueItem = dequeuedItem;
                                this.Items.Enqueue(currentQueueItem);
                            }
                        }
                    }
                }
                else if (part is XPathAxis pathAxis)
                {
                    if (pathAxis.Axis == CodePlex.XPathParser.XPathAxis.Root)
                    {
                        currentObject = baseObject.GetContainer();
                        var queueItem = new QueryPathQueueItem(currentObject);

                        this.Items.Enqueue(queueItem);

                        currentQueueItem = queueItem;
                    }
                    else
                    {
                        DebugUtils.Break();
                    }
                }
                else
                {
                    DebugUtils.Break();
                }
            }
        }