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

Reply via email to