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;
}