private void addChild(TreeElement child, Boolean checkDuplicate) { if (!isChildable()) { throw new SystemException("Can't add children to node that has data value!"); } if (child.multiplicity == TreeReference.INDEX_UNBOUND) { throw new SystemException("Cannot add child with an unbound index!"); } if (checkDuplicate) { TreeElement existingChild = getChild(child.name, child.multiplicity); if (existingChild != null) { throw new SystemException("Attempted to add duplicate child!"); } } // try to keep things in order int i = children.Count; if (child.getMult() == TreeReference.INDEX_TEMPLATE) { TreeElement anchor = getChild(child.getName(), 0); if (anchor != null) { i = children.IndexOf(anchor); } } else { TreeElement anchor = getChild(child.getName(), (child.getMult() == 0 ? TreeReference.INDEX_TEMPLATE : child.getMult() - 1)); if (anchor != null) { i = children.IndexOf(anchor) + 1; } } children.Insert(i, child); child.setParent(this); child.setRelevant(isRelevant(), true); child.setEnabled(isEnabled(), true); }
//rebuilding a node from an imported instance // there's a lot of error checking we could do on the received instance, but it's // easier to just ignore the parts that are incorrect public void populate(TreeElement incoming, FormDef f) { if (this.isLeaf()) { // check that incoming doesn't have children? IAnswerData value = incoming.getValue(); if (value == null) { this.setValue(null); } else if (this.dataType == Constants.DATATYPE_TEXT || this.dataType == Constants.DATATYPE_NULL) { this.setValue(value); // value is a StringData } else { String textVal = value.ToString(); IAnswerData typedVal = RestoreUtils.xfFact.parseData(textVal, this.dataType, this.getRef(), f); this.setValue(typedVal); } } else { ArrayList names = new ArrayList(); for (int i = 0; i < this.getNumChildren(); i++) { TreeElement child = this.getChildAt(i); if (!names.Contains(child.getName())) { names.Add(child.getName()); } } // remove all default repetitions from skeleton data model (_preserving_ templates, though) for (int i = 0; i < this.getNumChildren(); i++) { TreeElement child = this.getChildAt(i); if (child.repeatable && child.getMult() != TreeReference.INDEX_TEMPLATE) { this.removeChildAt(i); i--; } } // make sure ordering is preserved (needed for compliance with xsd schema) if (this.getNumChildren() != names.Count) { throw new SystemException("sanity check failed"); } for (int i = 0; i < this.getNumChildren(); i++) { TreeElement child = this.getChildAt(i); String expectedName = (String)names[i]; if (!child.getName().Equals(expectedName)) { TreeElement child2 = null; int j; for (j = i + 1; j < this.getNumChildren(); j++) { child2 = this.getChildAt(j); if (child2.getName().Equals(expectedName)) { break; } } if (j == this.getNumChildren()) { throw new SystemException("sanity check failed"); } this.removeChildAt(j); this.children.Insert(i, child2); } } // java i hate you so much for (int i = 0; i < this.getNumChildren(); i++) { TreeElement child = this.getChildAt(i); List <TreeElement> newChildren = incoming.getChildrenWithName(child.getName()); if (child.repeatable) { for (int k = 0; k < newChildren.Count; k++) { TreeElement newChild = child.deepCopy(true); newChild.setMult(k); this.children.Insert(i + k + 1, newChild); newChild.populate((TreeElement)newChildren[k], f); } i += newChildren.Count; } else { if (newChildren.Count == 0) { child.setRelevant(false); } else { child.populate((TreeElement)newChildren[0], f); } } } } }