public void importData(FormInstance dm) { name = (String)RestoreUtils.getValue("name", dm); formId = ((int)RestoreUtils.getValue("form-id", dm)); dateSaved = (DateTime)RestoreUtils.getValue("saved-on", dm); schema = (String)RestoreUtils.getValue("schema", dm); Boolean sent = RestoreUtils.getBoolean(RestoreUtils .getValue("sent", dm)); TreeElement names = dm.resolveReference(RestoreUtils.absRef("namespace", dm)); if (names != null) { for (int i = 0; i < names.getNumChildren(); i++) { TreeElement child = names.getChildAt(i); String name_ = child.getName(); Object value = RestoreUtils.getValue("namespace/" + name_, dm); if (value != null) { namespaces.Add(name_, value); } } } ///////////// throw new SystemException("FormInstance.importData(): must be updated to use new transport layer"); // if (sent) { // ITransportManager tm = TransportManager._(); // tm.markSent(id, false); // } ///////////// // IStorageUtility forms = StorageManager.getStorage(FormDef.STORAGE_KEY); // FormDef f = (FormDef)forms.read(formId); // setRoot(processSavedDataModel(dm.resolveReference(RestoreUtils.absRef("data", dm)), f.getDataModel(), f)); }
public TreeElement shallowCopy() { TreeElement newNode = new TreeElement(name, multiplicity); newNode.parent = parent; newNode.repeatable = repeatable; newNode.dataType = dataType; newNode.relevant = relevant; newNode.required = required; newNode.enabled = enabled; newNode.constraint = constraint; newNode.preloadHandler = preloadHandler; newNode.preloadParams = preloadParams; newNode.setAttributesFromSingleStringVector(getSingleStringAttributeVector()); if (value != null) { newNode.value = (IAnswerData)value.Clone(); } newNode.children = children; return(newNode); }
public TreeElement getChild(String name, int multiplicity) { if (name.Equals(TreeReference.NAME_WILDCARD)) { if (multiplicity == TreeReference.INDEX_TEMPLATE || this.children.Count < multiplicity + 1) { return(null); } return((TreeElement)this.children[multiplicity]); //droos: i'm suspicious of this } else { for (int i = 0; i < this.children.Count; i++) { TreeElement child = (TreeElement)this.children[i]; if (name.Equals(child.getName()) && child.getMult() == multiplicity) { return(child); } } } return(null); }
//return the tree reference that corresponds to this tree element public TreeReference getRef() { TreeElement elem = this; TreeReference ref_ = TreeReference.selfRef(); while (elem != null) { TreeReference step; if (elem.name != null) { step = TreeReference.selfRef(); step.add(elem.name, elem.multiplicity); } else { step = TreeReference.rootRef(); } ref_ = ref_.parent(step); elem = elem.parent; } return(ref_); }
//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); } } } } }
/* * (non-Javadoc) * * @see * org.javarosa.core.services.storage.utilities.Externalizable#writeExternal * (java.io.DataOutputStream) */ public void writeExternal(BinaryWriter out_renamed) { ExtUtil.writeString(out_renamed, ExtUtil.emptyIfNull(name)); ExtUtil.writeNumeric(out_renamed, multiplicity); ExtUtil.writeBool(out_renamed, repeatable); ExtUtil.write(out_renamed, new ExtWrapNullable(value == null ? null : new ExtWrapTagged(value))); // Jan 22, 2009 - [email protected] // old line: ExtUtil.write(out, new // ExtWrapList(ExtUtil.emptyIfNull(children))); // New Child serialization // 1. write null status as boolean // 2. write number of children // 3. for all child in children // 3.1 if child type == TreeElement write boolean true , then serialize // directly. // 3.2 if child type != TreeElement, write boolean false, then tagged // child if (children == null) { // 1. ExtUtil.writeBool(out_renamed, false); } else { // 1. ExtUtil.writeBool(out_renamed, true); // 2. ExtUtil.writeNumeric(out_renamed, children.Count); // 3. IEnumerator en = children.GetEnumerator(); while (en.MoveNext()) { TreeElement child = (TreeElement)en.Current; if (child.GetType() == typeof(TreeElement)) { // 3.1 ExtUtil.writeBool(out_renamed, true); child.writeExternal(out_renamed); } else { // 3.2 ExtUtil.writeBool(out_renamed, false); ExtUtil.write(out_renamed, new ExtWrapTagged(child)); } } } // end Jan 22, 2009 ExtUtil.writeNumeric(out_renamed, dataType); ExtUtil.writeBool(out_renamed, relevant); ExtUtil.writeBool(out_renamed, required); ExtUtil.writeBool(out_renamed, enabled); ExtUtil.writeBool(out_renamed, relevantInherited); ExtUtil.writeBool(out_renamed, enabledInherited); ExtUtil.write(out_renamed, new ExtWrapNullable(constraint)); // TODO: inefficient for repeats ExtUtil.writeString(out_renamed, ExtUtil.emptyIfNull(preloadHandler)); ExtUtil.writeString(out_renamed, ExtUtil.emptyIfNull(preloadParams)); ArrayList attStrings = getSingleStringAttributeVector(); ArrayList al = ExtUtil.emptyIfNull(attStrings); ExtUtil.write(out_renamed, new ExtWrapList(al)); }
/* ==== SERIALIZATION ==== */ /* * TODO: * * this new serialization scheme is kind of lame. ideally, we shouldn't have * to sub-class TreeElement at all; we should have an API that can * seamlessly represent complex data model objects (like weight history or * immunizations) as if they were explicity XML subtrees underneath the * parent TreeElement * * failing that, we should wrap this scheme in an ExternalizableWrapper */ /* * (non-Javadoc) * * @see * org.javarosa.core.services.storage.utilities.Externalizable#readExternal * (java.io.DataInputStream) */ public void readExternal(BinaryReader in_renamed, PrototypeFactory pf) { name = ExtUtil.nullIfEmpty(ExtUtil.readString(in_renamed)); multiplicity = ExtUtil.readInt(in_renamed); repeatable = ExtUtil.readBool(in_renamed); value = (IAnswerData)ExtUtil.read(in_renamed, new ExtWrapNullable(new ExtWrapTagged()), pf); // children = ExtUtil.nullIfEmpty((Vector)ExtUtil.read(in, new // ExtWrapList(TreeElement.class), pf)); // Jan 22, 2009 - [email protected] // old line: children = ExtUtil.nullIfEmpty((Vector)ExtUtil.read(in, new // ExtWrapList(TreeElement.class), pf)); // New Child deserialization // 1. read null status as boolean // 2. read number of children // 3. for i < number of children // 3.1 if read boolean true , then create TreeElement and deserialize // directly. // 3.2 if read boolean false then create tagged element and deserialize // child if (!ExtUtil.readBool(in_renamed)) { // 1. children = null; } else { children = new ArrayList(); // 2. int numChildren = (int)ExtUtil.readNumeric(in_renamed); // 3. for (int i = 0; i < numChildren; ++i) { Boolean normal = ExtUtil.readBool(in_renamed); TreeElement child; if (normal) { // 3.1 child = new TreeElement(); child.readExternal(in_renamed, pf); } else { // 3.2 child = (TreeElement)ExtUtil.read(in_renamed, new ExtWrapTagged(), pf); } child.setParent(this); children.Add(child); } } // end Jan 22, 2009 dataType = ExtUtil.readInt(in_renamed); relevant = ExtUtil.readBool(in_renamed); required = ExtUtil.readBool(in_renamed); enabled = ExtUtil.readBool(in_renamed); relevantInherited = ExtUtil.readBool(in_renamed); enabledInherited = ExtUtil.readBool(in_renamed); constraint = (Constraint)ExtUtil.read(in_renamed, new ExtWrapNullable( typeof(Constraint)), pf); preloadHandler = ExtUtil.nullIfEmpty(ExtUtil.readString(in_renamed)); preloadParams = ExtUtil.nullIfEmpty(ExtUtil.readString(in_renamed)); ArrayList attStrings = ExtUtil.nullIfEmpty((ArrayList)ExtUtil.read(in_renamed, new ExtWrapList(typeof(String)), pf)); setAttributesFromSingleStringVector(attStrings); }
/** * get value of attribute with namespace:name' in the vector * * @param index * @return String */ public String getAttributeValue(String namespace_, String name) { TreeElement element = getAttribute(namespace_, name); return(element == null ? null : getAttributeValue(element)); }
public void removeChild(TreeElement child) { children.Remove(child); }
/** * Add a child to this element * * @param child */ public void addChild(TreeElement child) { addChild(child, false); }
public void setParent(TreeElement parent) { this.parent = parent; }
/** * Creates a new data model using the root given. * * @param root * The root of the tree for this data model. */ public FormInstance(TreeElement root) { ID = -1; setFormId(-1); setRoot(root); }
/* * 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); }
// retrieve the template node for a given repeated node ref may be ambiguous // return null if node is not repeatable // assumes templates are built correctly and obey all data model validity rules public TreeElement getTemplate(TreeReference ref_) { TreeElement node = getTemplatePath(ref_); return(node == null ? null : node.repeatable?node : null); }
// 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); } } }