//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); }
//turn unambiguous ref into a generic ref public TreeReference genericize() { TreeReference genericRef = clone(); for (int i = 0; i < genericRef.size(); i++) { genericRef.setMultiplicity(i, INDEX_UNBOUND); } return(genericRef); }
//turn unambiguous ref into a generic ref public virtual TreeReference genericize() { TreeReference genericRef = Clone(); for (int i = 0; i < genericRef.size(); i++) { //TODO: It's not super clear whether template refs should get //genericized or not genericRef.setMultiplicity(i, INDEX_UNBOUND); } return(genericRef); }
//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); }
/* * 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); }