Esempio n. 1
0
        //TODO: merge anchor() and parent()

        public TreeReference contextualize(TreeReference contextRef)
        {
            if (!contextRef.isAbsolute())
            {
                return(null);
            }

            TreeReference newRef = anchor(contextRef);

            for (int i = 0; i < contextRef.size() && i < newRef.size(); i++)
            {
                //If the the contextRef can provide a definition for a wildcard, do so
                if (TreeReference.NAME_WILDCARD.Equals(newRef.getName(i)) && !TreeReference.NAME_WILDCARD.Equals(contextRef.getName(i)))
                {
                    newRef.names[i] = contextRef.getName(i);
                }

                if (contextRef.getName(i).Equals(newRef.getName(i)))
                {
                    newRef.setMultiplicity(i, contextRef.getMultiplicity(i));
                }
                else
                {
                    break;
                }
            }

            return(newRef);
        }
Esempio n. 2
0
        //returns true if 'this' is parent of 'child'
        //return true if 'this' equals 'child' only if properParent is false
        public Boolean isParentOf(TreeReference child, Boolean properParent)
        {
            if (refLevel != child.refLevel)
            {
                return(false);
            }
            if (child.size() < size() + (properParent ? 1 : 0))
            {
                return(false);
            }

            for (int i = 0; i < size(); i++)
            {
                if (!this.getName(i).Equals(child.getName(i)))
                {
                    return(false);
                }

                int parMult   = this.getMultiplicity(i);
                int childMult = child.getMultiplicity(i);
                if (parMult != INDEX_UNBOUND && parMult != childMult && !(i == 0 && parMult == 0 && childMult == INDEX_UNBOUND))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 3
0
        public TreeElement getTemplatePath(TreeReference ref_)
        {
            if (!ref_.isAbsolute())
            {
                return(null);
            }

            TreeElement node = root;

            for (int i = 0; i < ref_.size(); i++)
            {
                String name = ref_.getName(i);

                if (ref_.getMultiplicity(i) == TreeReference.INDEX_ATTRIBUTE)
                {
                    node = node.getAttribute(null, name);
                }
                else
                {
                    TreeElement newNode = node.getChild(name, TreeReference.INDEX_TEMPLATE);
                    if (newNode == null)
                    {
                        newNode = node.getChild(name, 0);
                    }
                    if (newNode == null)
                    {
                        return(null);
                    }
                    node = newNode;
                }
            }

            return(node);
        }
Esempio n. 4
0
        // same as resolveReference but return a vector containing all interstitial
        // nodes: top-level instance data node first, and target node last
        // returns null in all the same situations as resolveReference EXCEPT ref
        // '/' will instead return empty vector
        public ArrayList explodeReference(TreeReference ref_)
        {
            if (!ref_.isAbsolute())
            {
                return(null);
            }

            ArrayList   nodes = new ArrayList();
            TreeElement cur   = root;

            for (int i = 0; i < ref_.size(); i++)
            {
                String name = ref_.getName(i);
                int    mult = ref_.getMultiplicity(i);

                //If the next node down the line is an attribute
                if (mult == TreeReference.INDEX_ATTRIBUTE)
                {
                    //This is not the attribute we're testing
                    if (cur != root)
                    {
                        //Add the current node
                        nodes.Add(cur);
                    }
                    cur = cur.getAttribute(null, name);
                }

                //Otherwise, it's another child element
                else
                {
                    if (mult == TreeReference.INDEX_UNBOUND)
                    {
                        if (cur.getChildMultiplicity(name) == 1)
                        {
                            mult = 0;
                        }
                        else
                        {
                            // reference is not unambiguous
                            return(null);
                        }
                    }

                    if (cur != root)
                    {
                        nodes.Add(cur);
                    }

                    cur = cur.getChild(name, mult);
                    if (cur == null)
                    {
                        return(null);
                    }
                }
            }
            return(nodes);
        }
Esempio n. 5
0
        //TODO: merge anchor() and parent()

        public virtual TreeReference contextualize(TreeReference contextRef)
        {
            //TODO: Technically we should possibly be modifying context stuff here
            //instead of in the xpath stuff;
            if (!contextRef.Absolute)
            {
                return(null);
            }

            // I think contextualizing of absolute nodes still needs to be done.
            // They may contain predicates that need to be contextualized.

            TreeReference newRef = anchor(contextRef);

            // unclear...
            newRef.Context = contextRef.Context;

            //apply multiplicites and fill in wildcards as necessary based on the context ref
            for (int i = 0; i < contextRef.size() && i < newRef.size(); i++)
            {
                //If the the contextRef can provide a definition for a wildcard, do so
                if (TreeReference.NAME_WILDCARD.Equals(newRef.getName(i)) && !TreeReference.NAME_WILDCARD.Equals(contextRef.getName(i)))
                {
                    newRef.data.setElementAt(newRef.data.elementAt(i).setName(contextRef.getName(i)), i);
                }

                if (contextRef.getName(i).Equals(newRef.getName(i)))
                {
                    //We can't actually merge nodes if the newRef has predicates or filters
                    //on this expression, since those reset any existing resolutions which
                    //may have been done.
                    if (newRef.getPredicate(i) == null)
                    {
                        newRef.setMultiplicity(i, contextRef.getMultiplicity(i));
                    }
                }
                else
                {
                    break;
                }
            }

            return(newRef);
        }
Esempio n. 6
0
        public Boolean Equals(Object o)
        {
            if (this == o)
            {
                return(true);
            }
            else if (o is TreeReference)
            {
                TreeReference ref_ = (TreeReference)o;

                if (this.refLevel == ref_.refLevel && this.size() == ref_.size())
                {
                    for (int i = 0; i < this.size(); i++)
                    {
                        String nameA = this.getName(i);
                        String nameB = ref_.getName(i);
                        int    multA = this.getMultiplicity(i);
                        int    multB = ref_.getMultiplicity(i);

                        if (!nameA.Equals(nameB))
                        {
                            return(false);
                        }
                        else if (multA != multB)
                        {
                            if (i == 0 && (multA == 0 || multA == INDEX_UNBOUND) && (multB == 0 || multB == INDEX_UNBOUND))
                            {
                                // /data and /data[0] are functionally the same
                            }
                            else
                            {
                                return(false);
                            }
                        }
                    }
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
Esempio n. 7
0
        // take a ref that unambiguously refers to a single node and return that node
        // return null if ref is ambiguous, node does not exist, ref is relative, or ref is '/'
        // can be used to retrieve template nodes
        public TreeElement resolveReference(TreeReference ref_)
        {
            if (!ref_.isAbsolute())
            {
                return(null);
            }

            TreeElement node = root;

            for (int i = 0; i < ref_.size(); i++)
            {
                String name = ref_.getName(i);
                int    mult = ref_.getMultiplicity(i);

                if (mult == TreeReference.INDEX_ATTRIBUTE)
                {
                    //Should we possibly just return here?
                    //I guess technically we could step back...
                    node = node.getAttribute(null, name);
                    continue;
                }
                if (mult == TreeReference.INDEX_UNBOUND)
                {
                    if (node.getChildMultiplicity(name) == 1)
                    {
                        mult = 0;
                    }
                    else
                    {
                        // reference is not unambiguous
                        node = null;
                        break;
                    }
                }

                node = node.getChild(name, mult);
                if (node == null)
                {
                    break;
                }
            }

            return(node == root ? null : node);  // never return a reference to '/'
        }
Esempio n. 8
0
        public override bool Equals(System.Object o)
        {
            if (this == o)
            {
                return(true);
            }
            else if (o is TreeReference)
            {
                TreeReference ref_Renamed = (TreeReference)o;

                if (this.refLevel == ref_Renamed.refLevel && this.size() == ref_Renamed.size())
                {
                    for (int i = 0; i < this.size(); i++)
                    {
                        System.String nameA = this.getName(i);
                        System.String nameB = ref_Renamed.getName(i);
                        int           multA = this.getMultiplicity(i);
                        int           multB = ref_Renamed.getMultiplicity(i);



                        if (!nameA.Equals(nameB))
                        {
                            return(false);
                        }
                        else if (multA != multB)
                        {
                            if (i == 0 && (multA == 0 || multA == INDEX_UNBOUND) && (multB == 0 || multB == INDEX_UNBOUND))
                            {
                                // /data and /data[0] are functionally the same
                            }
                            else
                            {
                                return(false);
                            }
                        }
                        else if (predA != null && predB != null)
                        {
                            if (predA.size() != predB.size())
                            {
                                return(false);
                            }
                            for (int j = 0; j < predA.size(); ++j)
                            {
                                if (!predA.elementAt(j).equals(predB.elementAt(j)))
                                {
                                    return(false);
                                }
                            }
                        }
                        else if ((predA == null && predB != null) || (predA != null && predB == null))
                        {
                            return(false);
                        }
                    }
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
Esempio n. 9
0
        /*
         * create the specified node in the tree, creating all intermediary nodes at
         * each step, if necessary. if specified node already exists, return null
         *
         * creating a duplicate node is only allowed at the final step. it will be
         * done if the multiplicity of the last step is ALL or equal to the count of
         * nodes already there
         *
         * at intermediate steps, the specified existing node is used; if
         * multiplicity is ALL: if no nodes exist, a new one is created; if one node
         * exists, it is used; if multiple nodes exist, it's an error
         *
         * return the newly-created node; modify ref so that it's an unambiguous ref
         * to the node
         */
        private TreeElement createNode(TreeReference ref_)
        {
            TreeElement node = root;

            for (int k = 0; k < ref_.size(); k++)
            {
                String name  = ref_.getName(k);
                int    count = node.getChildMultiplicity(name);
                int    mult  = ref_.getMultiplicity(k);

                TreeElement child;
                if (k < ref_.size() - 1)
                {
                    if (mult == TreeReference.INDEX_UNBOUND)
                    {
                        if (count > 1)
                        {
                            return(null); // don't know which node to use
                        }
                        else
                        {
                            // will use existing (if one and only one) or create new
                            mult = 0;
                            ref_.setMultiplicity(k, 0);
                        }
                    }

                    // fetch
                    child = node.getChild(name, mult);
                    if (child == null)
                    {
                        if (mult == 0)
                        {
                            // create
                            child = new TreeElement(name, count);
                            node.addChild(child);
                            ref_.setMultiplicity(k, count);
                        }
                        else
                        {
                            return(null); // intermediate node does not exist
                        }
                    }
                }
                else
                {
                    if (mult == TreeReference.INDEX_UNBOUND || mult == count)
                    {
                        if (k == 0 && root.getNumChildren() != 0)
                        {
                            return(null); // can only be one top-level node, and it
                            // already exists
                        }

                        if (!node.isChildable())
                        {
                            return(null); // current node can't have children
                        }

                        // create new
                        child = new TreeElement(name, count);
                        node.addChild(child);
                        ref_.setMultiplicity(k, count);
                    }
                    else
                    {
                        return(null); // final node must be a newly-created node
                    }
                }

                node = child;
            }

            return(node);
        }
Esempio n. 10
0
        // recursive helper function for expandReference
        // sourceRef: original path we're matching against
        // node: current node that has matched the sourceRef thus far
        // templateRef: explicit path that refers to the current node
        // refs: Vector to collect matching paths; if 'node' is a target node that
        // matches sourceRef, templateRef is added to refs
        private void expandReference(TreeReference sourceRef, TreeElement node, List <TreeReference> refs, Boolean includeTemplates)
        {
            int depth = node.getDepth();

            if (depth == sourceRef.size())
            {
                refs.Add(node.getRef());
            }
            else
            {
                String             name = sourceRef.getName(depth);
                int                mult = sourceRef.getMultiplicity(depth);
                List <TreeElement> set  = new List <TreeElement>();

                if (node.getNumChildren() > 0)
                {
                    if (mult == TreeReference.INDEX_UNBOUND)
                    {
                        int count = node.getChildMultiplicity(name);
                        for (int i = 0; i < count; i++)
                        {
                            TreeElement child = node.getChild(name, i);
                            if (child != null)
                            {
                                set.Add(child);
                            }
                            else
                            {
                                throw new InvalidOperationException(); // missing/non-sequential
                                // nodes
                            }
                        }
                        if (includeTemplates)
                        {
                            TreeElement template = node.getChild(name, TreeReference.INDEX_TEMPLATE);
                            if (template != null)
                            {
                                set.Add(template);
                            }
                        }
                    }
                    else if (mult != TreeReference.INDEX_ATTRIBUTE)
                    {
                        //TODO: Make this test mult >= 0?
                        //If the multiplicity is a simple integer, just get
                        //the appropriate child
                        TreeElement child = node.getChild(name, mult);
                        if (child != null)
                        {
                            set.Add(child);
                        }
                    }
                }

                if (mult == TreeReference.INDEX_ATTRIBUTE)
                {
                    TreeElement attribute = node.getAttribute(null, name);
                    set.Add(attribute);
                }

                for (IEnumerator e = set.GetEnumerator(); e.MoveNext();)
                {
                    expandReference(sourceRef, (TreeElement)e.Current, refs, includeTemplates);
                }
            }
        }