示例#1
0
        // determine if nodes are homogeneous, meaning their descendant structure is 'identical' for repeat purposes
        // identical means all children match, and the children's children match, and so on
        // repeatable children are ignored; as they do not have to exist in the same quantity for nodes to be homogeneous
        // however, the child repeatable nodes MUST be verified amongst themselves for homogeneity later
        // this function ignores the names of the two nodes
        public static Boolean isHomogeneous(TreeElement a, TreeElement b)
        {
            if (a.isLeaf() && b.isLeaf())
            {
                return(true);
            }
            else if (a.isChildable() && b.isChildable())
            {
                // verify that every (non-repeatable) node in a exists in b and vice
                // versa
                for (int k = 0; k < 2; k++)
                {
                    TreeElement n1 = (k == 0 ? a : b);
                    TreeElement n2 = (k == 0 ? b : a);

                    for (int i = 0; i < n1.getNumChildren(); i++)
                    {
                        TreeElement child1 = n1.getChildAt(i);
                        if (child1.repeatable)
                        {
                            continue;
                        }
                        TreeElement child2 = n2.getChild(child1.getName(), 0);
                        if (child2 == null)
                        {
                            return(false);
                        }
                        if (child2.repeatable)
                        {
                            throw new SystemException("shouldn't happen");
                        }
                    }
                }

                // compare children
                for (int i = 0; i < a.getNumChildren(); i++)
                {
                    TreeElement childA = a.getChildAt(i);
                    if (childA.repeatable)
                    {
                        continue;
                    }
                    TreeElement childB = b.getChild(childA.getName(), 0);
                    if (!isHomogeneous(childA, childB))
                    {
                        return(false);
                    }
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#2
0
        // for making new repeat instances; 'from' and 'to' must be unambiguous
        // references EXCEPT 'to' may be ambiguous at its final step
        // return true is successfully copied, false otherwise
        public TreeElement copyNode(TreeElement src, TreeReference to)
        {
            if (!to.isAbsolute())
            {
                throw new InvalidReferenceException("Destination reference must be absolute for copying", to);
            }

            // strip out dest node info and get dest parent
            String        dstName  = to.getNameLast();
            int           dstMult  = to.getMultLast();
            TreeReference toParent = to.getParentRef();

            TreeElement parent = resolveReference(toParent);

            if (parent == null)
            {
                throw new InvalidReferenceException("Null parent reference whle attempting to copy", toParent);
            }
            if (!parent.isChildable())
            {
                throw new InvalidReferenceException("Invalid Parent Node: cannot accept children.", toParent);
            }

            if (dstMult == TreeReference.INDEX_UNBOUND)
            {
                dstMult = parent.getChildMultiplicity(dstName);
            }
            else if (parent.getChild(dstName, dstMult) != null)
            {
                throw new InvalidReferenceException("Destination already exists!", to);
            }

            TreeElement dest = src.deepCopy(false);

            dest.setName(dstName);
            dest.multiplicity = dstMult;
            parent.addChild(dest);
            return(dest);
        }
示例#3
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);
        }