kevinoneill 2003/08/05 22:48:14
Modified: java/src/org/apache/xindice/core/query XPathQueryResolver.java Log: PR: 22155 Throw an exception when the XPath query results in types we can't handle. Revision Changes Path 1.15 +160 -139 xml-xindice/java/src/org/apache/xindice/core/query/XPathQueryResolver.java Index: XPathQueryResolver.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/core/query/XPathQueryResolver.java,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- XPathQueryResolver.java 1 Aug 2003 19:40:19 -0000 1.14 +++ XPathQueryResolver.java 6 Aug 2003 05:48:14 -0000 1.15 @@ -59,9 +59,19 @@ * $Id$ */ +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.xml.transform.ErrorListener; +import javax.xml.transform.TransformerException; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xindice.core.Collection; +import org.apache.xindice.core.DBException; import org.apache.xindice.core.data.Key; import org.apache.xindice.core.data.NodeSet; import org.apache.xindice.core.data.RecordSet; @@ -82,6 +92,7 @@ import org.apache.xindice.util.Configuration; import org.apache.xindice.util.SimpleConfigurable; import org.apache.xindice.util.XindiceException; +import org.apache.xindice.util.XindiceRuntimeException; import org.apache.xindice.xml.NamespaceMap; import org.apache.xindice.xml.SymbolTable; import org.apache.xindice.xml.dom.DBDocument; @@ -99,18 +110,11 @@ import org.apache.xpath.objects.XNumber; import org.apache.xpath.objects.XObject; import org.apache.xpath.objects.XString; - import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.traversal.NodeIterator; - -import javax.xml.transform.ErrorListener; -import javax.xml.transform.TransformerException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.SortedSet; -import java.util.TreeSet; +import org.xmldb.api.base.ErrorCodes; +import org.xmldb.api.base.XMLDBException; /** * XPathQueryResolver @@ -130,7 +134,8 @@ private static Log log = LogFactory.getLog("org.apache.xindice.core"); // Maps Xalan Comparisons To IndexQuery - private static final int[] OpMap = {IndexQuery.NEQ, IndexQuery.EQ, IndexQuery.LEQ, IndexQuery.LT, IndexQuery.GEQ, IndexQuery.GT}; + private static final int[] OpMap = + { IndexQuery.NEQ, IndexQuery.EQ, IndexQuery.LEQ, IndexQuery.LT, IndexQuery.GEQ, IndexQuery.GT }; // Maps XPath Functions To Internal IDs (These are Xalan IDs) public static final int FUNC_NOT = 11; @@ -273,7 +278,7 @@ if (e instanceof QueryException) { throw (QueryException) e.fillInStackTrace(); } - throw new ProcessingException("Error executing XPath query"); + throw new ProcessingException("Error executing XPath query: " + e.getMessage()); } } @@ -316,88 +321,88 @@ switch (op) { - case OpCodes.OP_LOCATIONPATH: + case OpCodes.OP_LOCATIONPATH : return evalLocationPath(owner, pos); - case OpCodes.OP_ARGUMENT: - case OpCodes.OP_XPATH: - case OpCodes.OP_PREDICATE: + case OpCodes.OP_ARGUMENT : + case OpCodes.OP_XPATH : + case OpCodes.OP_PREDICATE : return evaluate(owner, Compiler.getFirstChildPos(pos)); - case OpCodes.OP_OR: - case OpCodes.OP_AND: + case OpCodes.OP_OR : + case OpCodes.OP_AND : return evalSetComparison(op, owner, pos); - case OpCodes.OP_NOTEQUALS: - case OpCodes.OP_EQUALS: - case OpCodes.OP_LTE: - case OpCodes.OP_LT: - case OpCodes.OP_GTE: - case OpCodes.OP_GT: + case OpCodes.OP_NOTEQUALS : + case OpCodes.OP_EQUALS : + case OpCodes.OP_LTE : + case OpCodes.OP_LT : + case OpCodes.OP_GTE : + case OpCodes.OP_GT : return evalValComparison(op, owner, pos); - case OpCodes.OP_PLUS: - case OpCodes.OP_MINUS: - case OpCodes.OP_MULT: - case OpCodes.OP_DIV: - case OpCodes.OP_MOD: - case OpCodes.OP_QUO: + case OpCodes.OP_PLUS : + case OpCodes.OP_MINUS : + case OpCodes.OP_MULT : + case OpCodes.OP_DIV : + case OpCodes.OP_MOD : + case OpCodes.OP_QUO : return evalMathOperation(op, owner, pos); - case OpCodes.OP_NEG: - case OpCodes.OP_STRING: - case OpCodes.OP_BOOL: - case OpCodes.OP_NUMBER: + case OpCodes.OP_NEG : + case OpCodes.OP_STRING : + case OpCodes.OP_BOOL : + case OpCodes.OP_NUMBER : return evalUnaryOperation(op, owner, pos); - case OpCodes.OP_UNION: + case OpCodes.OP_UNION : return evalUnion(owner, pos); - case OpCodes.OP_VARIABLE: + case OpCodes.OP_VARIABLE : break; - case OpCodes.OP_GROUP: + case OpCodes.OP_GROUP : return evaluate(owner, Compiler.getFirstChildPos(pos)); - case OpCodes.OP_EXTFUNCTION: + case OpCodes.OP_EXTFUNCTION : break; - case OpCodes.OP_FUNCTION: + case OpCodes.OP_FUNCTION : return evalFunction(owner, pos); - case OpCodes.FROM_ANCESTORS: - case OpCodes.FROM_ANCESTORS_OR_SELF: - case OpCodes.FROM_ATTRIBUTES: - case OpCodes.FROM_CHILDREN: - case OpCodes.FROM_DESCENDANTS: - case OpCodes.FROM_DESCENDANTS_OR_SELF: - case OpCodes.FROM_FOLLOWING: - case OpCodes.FROM_FOLLOWING_SIBLINGS: - case OpCodes.FROM_PARENT: - case OpCodes.FROM_PRECEDING: - case OpCodes.FROM_PRECEDING_SIBLINGS: - case OpCodes.FROM_NAMESPACE: - case OpCodes.FROM_SELF: - case OpCodes.FROM_ROOT: + case OpCodes.FROM_ANCESTORS : + case OpCodes.FROM_ANCESTORS_OR_SELF : + case OpCodes.FROM_ATTRIBUTES : + case OpCodes.FROM_CHILDREN : + case OpCodes.FROM_DESCENDANTS : + case OpCodes.FROM_DESCENDANTS_OR_SELF : + case OpCodes.FROM_FOLLOWING : + case OpCodes.FROM_FOLLOWING_SIBLINGS : + case OpCodes.FROM_PARENT : + case OpCodes.FROM_PRECEDING : + case OpCodes.FROM_PRECEDING_SIBLINGS : + case OpCodes.FROM_NAMESPACE : + case OpCodes.FROM_SELF : + case OpCodes.FROM_ROOT : return evalAxis(op, owner, pos); - case OpCodes.NODENAME: - case OpCodes.OP_LITERAL: - case OpCodes.OP_NUMBERLIT: + case OpCodes.NODENAME : + case OpCodes.OP_LITERAL : + case OpCodes.OP_NUMBERLIT : return evalLiteral(owner, pos); - case OpCodes.NODETYPE_TEXT: - case OpCodes.NODETYPE_NODE: + case OpCodes.NODETYPE_TEXT : + case OpCodes.NODETYPE_NODE : return owner; - case OpCodes.NODETYPE_ANYELEMENT: - case OpCodes.ELEMWILDCARD: + case OpCodes.NODETYPE_ANYELEMENT : + case OpCodes.ELEMWILDCARD : return WILDCARD; - case OpCodes.NODETYPE_ROOT: - case OpCodes.NODETYPE_COMMENT: - case OpCodes.NODETYPE_PI: - case OpCodes.NODETYPE_FUNCTEST: + case OpCodes.NODETYPE_ROOT : + case OpCodes.NODETYPE_COMMENT : + case OpCodes.NODETYPE_PI : + case OpCodes.NODETYPE_FUNCTEST : break; default : @@ -456,7 +461,7 @@ Object right = evaluate(owner, r); if (right instanceof NamedKeys && ((NamedKeys) right).keys != null) { - Key[][] keys = new Key[][]{((NamedKeys) left).keys, ((NamedKeys) right).keys}; + Key[][] keys = new Key[][] {((NamedKeys) left).keys, ((NamedKeys) right).keys }; return new NamedKeys(null, false, QueryEngine.orKeySets(keys)); } } @@ -475,7 +480,7 @@ NamedKeys nkl = left instanceof NamedKeys ? (NamedKeys) left : null; NamedKeys nkr = right instanceof NamedKeys ? (NamedKeys) right : null; if (nkl != null && nkr != null && nkl.keys != null && nkr.keys != null) { - Key[][] keys = new Key[][]{nkl.keys, nkr.keys}; + Key[][] keys = new Key[][] { nkl.keys, nkr.keys }; if (op == OpCodes.OP_OR) return new NamedKeys(null, false, QueryEngine.orKeySets(keys)); else @@ -497,17 +502,17 @@ if ((left instanceof XObject) && (right instanceof XObject)) { switch (op) { - case OpCodes.OP_NOTEQUALS: + case OpCodes.OP_NOTEQUALS : return new XBoolean(((XObject) left).notEquals((XObject) right)); - case OpCodes.OP_EQUALS: + case OpCodes.OP_EQUALS : return new XBoolean(((XObject) left).equals((XObject) right)); - case OpCodes.OP_LTE: + case OpCodes.OP_LTE : return new XBoolean(((XObject) left).lessThanOrEqual((XObject) right)); - case OpCodes.OP_LT: + case OpCodes.OP_LT : return new XBoolean(((XObject) left).lessThan((XObject) right)); - case OpCodes.OP_GTE: + case OpCodes.OP_GTE : return new XBoolean(((XObject) left).greaterThanOrEqual((XObject) right)); - case OpCodes.OP_GT: + case OpCodes.OP_GT : return new XBoolean(((XObject) left).greaterThan((XObject) right)); default : return null; // Won't happen @@ -523,17 +528,17 @@ XObject right = (XObject) evaluate(owner, rc); switch (op) { - case OpCodes.OP_PLUS: + case OpCodes.OP_PLUS : return new XNumber(left.num() + right.num()); - case OpCodes.OP_MINUS: + case OpCodes.OP_MINUS : return new XNumber(left.num() - right.num()); - case OpCodes.OP_MULT: + case OpCodes.OP_MULT : return new XNumber(left.num() * right.num()); - case OpCodes.OP_DIV: + case OpCodes.OP_DIV : return new XNumber(left.num() / right.num()); - case OpCodes.OP_MOD: + case OpCodes.OP_MOD : return new XNumber(left.num() % right.num()); - case OpCodes.OP_QUO: + case OpCodes.OP_QUO : return new XNumber(left.num() / right.num()); default : return null; // Won't happen @@ -543,13 +548,13 @@ private Object evalUnaryOperation(int op, String owner, int pos) throws Exception { XObject val = (XObject) evaluate(owner, Compiler.getFirstChildPos(pos)); switch (op) { - case OpCodes.OP_NEG: + case OpCodes.OP_NEG : return new XNumber(-val.num()); - case OpCodes.OP_STRING: + case OpCodes.OP_STRING : return new XString(val.str()); - case OpCodes.OP_BOOL: + case OpCodes.OP_BOOL : return new XBoolean(val.bool()); - case OpCodes.OP_NUMBER: + case OpCodes.OP_NUMBER : return new XNumber(val.num()); default : return null; // Won't happen @@ -569,41 +574,41 @@ } switch (id) { - case FUNC_BOOLEAN: + case FUNC_BOOLEAN : return funcBoolean(args); - case FUNC_CEILING: + case FUNC_CEILING : return funcCeiling(args); - case FUNC_CONCAT: + case FUNC_CONCAT : return funcConcat(args); - case FUNC_CONTAINS: + case FUNC_CONTAINS : return funcContains(args); - case FUNC_FALSE: + case FUNC_FALSE : return XBoolean.S_FALSE; - case FUNC_FLOOR: + case FUNC_FLOOR : return funcFloor(args); - case FUNC_NORMALIZE_SPACE: + case FUNC_NORMALIZE_SPACE : return funcNormalizeSpace(args); - case FUNC_NOT: + case FUNC_NOT : return funcNot(args); - case FUNC_NUMBER: + case FUNC_NUMBER : return funcNumber(args); - case FUNC_ROUND: + case FUNC_ROUND : return funcRound(args); - case FUNC_STARTS_WITH: + case FUNC_STARTS_WITH : return funcStartsWith(owner, args); - case FUNC_STRING: + case FUNC_STRING : return funcString(args); - case FUNC_STRING_LENGTH: + case FUNC_STRING_LENGTH : return funcStringLength(args); - case FUNC_SUBSTRING: + case FUNC_SUBSTRING : return funcSubstring(args); - case FUNC_SUBSTRING_AFTER: + case FUNC_SUBSTRING_AFTER : return funcSubstringAfter(args); - case FUNC_SUBSTRING_BEFORE: + case FUNC_SUBSTRING_BEFORE : return funcSubstringBefore(args); - case FUNC_TRANSLATE: + case FUNC_TRANSLATE : return funcTranslate(args); - case FUNC_TRUE: + case FUNC_TRUE : return XBoolean.S_TRUE; default : return null; @@ -654,9 +659,9 @@ private Object evalLiteral(String owner, int pos) throws Exception { int idx = cmp.getOp(Compiler.getFirstChildPos(pos)); switch (idx) { - case OpCodes.EMPTY: + case OpCodes.EMPTY : return owner; - case OpCodes.ELEMWILDCARD: + case OpCodes.ELEMWILDCARD : return WILDCARD; default : return cmp.getToken(idx); @@ -914,13 +919,13 @@ // Set the type for the index String type = null; switch (objType) { - case XObject.CLASS_BOOLEAN: + case XObject.CLASS_BOOLEAN : type = "boolean"; break; - case XObject.CLASS_NUMBER: + case XObject.CLASS_NUMBER : type = "double"; break; - case XObject.CLASS_STRING: + case XObject.CLASS_STRING : if (ps.indexOf('@') != -1) type = "string"; else @@ -949,7 +954,10 @@ * @return The resulting Keys (if any) */ private Object queryComparison(int op, String owner, Object left, Object right) { - if (!((left instanceof NamedKeys) && (right instanceof XObject) || (left instanceof XObject) && (right instanceof NamedKeys))) + if (!((left instanceof NamedKeys) + && (right instanceof XObject) + || (left instanceof XObject) + && (right instanceof NamedKeys))) return null; // How'd we get here? op = OpMap[op - OpCodes.OP_NOTEQUALS]; @@ -978,22 +986,22 @@ String value = obj.str(); switch (op) { - case IndexQuery.NEQ: + case IndexQuery.NEQ : iq = new IndexQueryNEQ(pattern, value); break; - case IndexQuery.EQ: + case IndexQuery.EQ : iq = new IndexQueryEQ(pattern, value); break; - case IndexQuery.LEQ: + case IndexQuery.LEQ : iq = new IndexQueryLEQ(pattern, value); break; - case IndexQuery.LT: + case IndexQuery.LT : iq = new IndexQueryLT(pattern, value); break; - case IndexQuery.GEQ: + case IndexQuery.GEQ : iq = new IndexQueryGEQ(pattern, value); break; - case IndexQuery.GT: + case IndexQuery.GT : iq = new IndexQueryGT(pattern, value); break; default : @@ -1037,7 +1045,6 @@ public Node node; public ResultSet(Collection context, PrefixResolver pr, Key[] keySet, String query) { - //System.out.println("Query: "+query); this.context = context; this.pr = pr; this.keySet = keySet; @@ -1063,39 +1070,48 @@ } }; - prepareNextNode(); + try { + prepareNextNode(); + } catch (Exception e) { + throw new XindiceRuntimeException(e.getMessage()); + } } - private void prepareNextNode() { + private void prepareNextNode() throws XMLDBException, TransformerException, DBException { node = null; + while (keyPos < keySet.length) { - try { - //System.out.println(" Key: "+keySet[keyPos]); - DBDocument d = (DBDocument) context.getDocument(keySet[keyPos++]); - if (d == null) - continue; - - Node n = d.getDocumentElement(); - - XPathContext xpc = new XPathContext(); - PrefixResolver pfx; - if (pr == null) { - pfx = new PrefixResolverDefault(d.getDocumentElement()); + DBDocument d = (DBDocument) context.getDocument(keySet[keyPos++]); + if (d == null) + continue; + + Node n = d.getDocumentElement(); + + XPathContext xpc = new XPathContext(); + PrefixResolver pfx; + if (pr == null) { + pfx = new PrefixResolverDefault(d.getDocumentElement()); + xp = new XPath(query, null, pfx, XPath.SELECT, errors); + } else { + pfx = pr; + if (xp == null) xp = new XPath(query, null, pfx, XPath.SELECT, errors); - } else { - pfx = pr; - if (xp == null) - xp = new XPath(query, null, pfx, XPath.SELECT, errors); - } + } + + final XObject xobject = xp.execute(xpc, n, pfx); - ni = xp.execute(xpc, n, pfx).nodeset(); + switch (xobject.getType()) { + default : + throw new XMLDBException(ErrorCodes.NOT_IMPLEMENTED, "Only nodeset results are implemented at this time."); - node = ni.nextNode(); - if (node != null) + case XObject.CLASS_NODESET : + ni = xobject.nodeset(); + node = ni.nextNode(); break; - } catch (Exception e) { - log.warn(e); } + + if (node != null) + break; } } @@ -1107,8 +1123,13 @@ Node n = node; node = ni.nextNode(); - if (node == null) - prepareNextNode(); + if (node == null) { + try { + prepareNextNode(); + } catch (Exception e) { + throw new XindiceRuntimeException(e.getMessage()); + } + } return n; }