public synchronized TemplateModel executeQuery(Object context, String xpathQuery) throws TemplateModelException { if (!(context instanceof Node)) { if (context != null) { if (isNodeList(context)) { int cnt = ((List) context).size(); if (cnt != 0) { throw new TemplateModelException( "Cannot perform an XPath query against a node set of " + cnt + " nodes. Expecting a single node." + ERRMSG_RECOMMEND_JAXEN); } else { throw new TemplateModelException(ERRMSG_EMPTY_NODE_SET); } } else { throw new TemplateModelException( "Cannot perform an XPath query against a " + context.getClass().getName() + ". Expecting a single org.w3c.dom.Node."); } } else { throw new TemplateModelException(ERRMSG_EMPTY_NODE_SET); } } Node node = (Node) context; try { XPath xpath = new XPath(xpathQuery, null, customPrefixResolver, XPath.SELECT, null); int ctxtNode = xpathContext.getDTMHandleFromNode(node); XObject xresult = xpath.execute(xpathContext, ctxtNode, customPrefixResolver); if (xresult instanceof XNodeSet) { NodeListModel result = new NodeListModel(node); result.xpathSupport = this; NodeIterator nodeIterator = xresult.nodeset(); Node n; do { n = nodeIterator.nextNode(); if (n != null) { result.add(n); } } while (n != null); return result.size() == 1 ? result.get(0) : result; } if (xresult instanceof XBoolean) { return ((XBoolean) xresult).bool() ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE; } if (xresult instanceof XNull) { return null; } if (xresult instanceof XString) { return new SimpleScalar(xresult.toString()); } if (xresult instanceof XNumber) { return new SimpleNumber(new Double(((XNumber) xresult).num())); } throw new TemplateModelException("Cannot deal with type: " + xresult.getClass().getName()); } catch (TransformerException te) { throw new TemplateModelException(te); } }
// can be overwritten protected JMenuItem buildJMenuItem(XObject xobject, int valueType) { if (valueType == COMPATIBLE_VALUE) { return new JMenuItem(xobject.getText()); } else if (valueType == CURRENT_VALUE) { return new JMenuItem("> " + xobject.getText()); } else if (valueType == NULL_VALUE) { return new JMenuItem("null"); } else { return null; } }
/** * Tell if two objects are functionally equal. * * @param obj2 Object to compare this to * @return true if the two objects are equal * @throws javax.xml.transform.TransformerException */ public boolean equals(XObject obj2) { // In order to handle the 'all' semantics of // nodeset comparisons, we always call the // nodeset function. int t = obj2.getType(); try { if (XObject.CLASS_NODESET == t) return obj2.equals(this); // If at least one object to be compared is a boolean, then each object // to be compared is converted to a boolean as if by applying the // boolean function. else if (XObject.CLASS_BOOLEAN == t) return obj2.bool() == bool(); // Otherwise, if at least one object to be compared is a number, then each object // to be compared is converted to a number as if by applying the number function. else if (XObject.CLASS_NUMBER == t) return obj2.num() == num(); } catch (javax.xml.transform.TransformerException te) { throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(te); } // Otherwise, both objects to be compared are converted to strings as // if by applying the string function. return xstr().equals(obj2.xstr()); }
/** * Tell if one object is less than the other. * * @param obj2 Object to compare this nodeset to * @param comparator Comparator to use * @return See the comments below for each object type comparison * @throws javax.xml.transform.TransformerException */ public boolean compare(XObject obj2, Comparator comparator) throws javax.xml.transform.TransformerException { boolean result = false; int type = obj2.getType(); if (XObject.CLASS_NODESET == type) { // %OPT% This should be XMLString based instead of string based... // From http://www.w3.org/TR/xpath: // If both objects to be compared are node-sets, then the comparison // will be true if and only if there is a node in the first node-set // and a node in the second node-set such that the result of performing // the comparison on the string-values of the two nodes is true. // Note this little gem from the draft: // NOTE: If $x is bound to a node-set, then $x="foo" // does not mean the same as not($x!="foo"): the former // is true if and only if some node in $x has the string-value // foo; the latter is true if and only if all nodes in $x have // the string-value foo. DTMIterator list1 = iterRaw(); DTMIterator list2 = ((XNodeSet) obj2).iterRaw(); int node1; java.util.Vector node2Strings = null; while (DTM.NULL != (node1 = list1.nextNode())) { XMLString s1 = getStringFromNode(node1); if (null == node2Strings) { int node2; while (DTM.NULL != (node2 = list2.nextNode())) { XMLString s2 = getStringFromNode(node2); if (comparator.compareStrings(s1, s2)) { result = true; break; } if (null == node2Strings) node2Strings = new java.util.Vector(); node2Strings.addElement(s2); } } else { int n = node2Strings.size(); for (int i = 0; i < n; i++) { if (comparator.compareStrings(s1, (XMLString) node2Strings.elementAt(i))) { result = true; break; } } } } list1.reset(); list2.reset(); } else if (XObject.CLASS_BOOLEAN == type) { // From http://www.w3.org/TR/xpath: // If one object to be compared is a node-set and the other is a boolean, // then the comparison will be true if and only if the result of // performing the comparison on the boolean and on the result of // converting the node-set to a boolean using the boolean function // is true. double num1 = bool() ? 1.0 : 0.0; double num2 = obj2.num(); result = comparator.compareNumbers(num1, num2); } else if (XObject.CLASS_NUMBER == type) { // From http://www.w3.org/TR/xpath: // If one object to be compared is a node-set and the other is a number, // then the comparison will be true if and only if there is a // node in the node-set such that the result of performing the // comparison on the number to be compared and on the result of // converting the string-value of that node to a number using // the number function is true. DTMIterator list1 = iterRaw(); double num2 = obj2.num(); int node; while (DTM.NULL != (node = list1.nextNode())) { double num1 = getNumberFromNode(node); if (comparator.compareNumbers(num1, num2)) { result = true; break; } } list1.reset(); } else if (XObject.CLASS_RTREEFRAG == type) { XMLString s2 = obj2.xstr(); DTMIterator list1 = iterRaw(); int node; while (DTM.NULL != (node = list1.nextNode())) { XMLString s1 = getStringFromNode(node); if (comparator.compareStrings(s1, s2)) { result = true; break; } } list1.reset(); } else if (XObject.CLASS_STRING == type) { // From http://www.w3.org/TR/xpath: // If one object to be compared is a node-set and the other is a // string, then the comparison will be true if and only if there // is a node in the node-set such that the result of performing // the comparison on the string-value of the node and the other // string is true. XMLString s2 = obj2.xstr(); DTMIterator list1 = iterRaw(); int node; while (DTM.NULL != (node = list1.nextNode())) { XMLString s1 = getStringFromNode(node); if (comparator.compareStrings(s1, s2)) { result = true; break; } } list1.reset(); } else { result = comparator.compareNumbers(this.num(), obj2.num()); } return result; }