Search in sources :

Example 31 with InvalidQueryException

use of javax.jcr.query.InvalidQueryException in project jackrabbit by apache.

the class LuceneQueryBuilder method visit.

public Object visit(RelationQueryNode node, Object data) throws RepositoryException {
    PathQueryNode relPath = node.getRelativePath();
    if (relPath == null && node.getOperation() != QueryConstants.OPERATION_SIMILAR && node.getOperation() != QueryConstants.OPERATION_SPELLCHECK) {
        exceptions.add(new InvalidQueryException("@* not supported in predicate"));
        return data;
    }
    LocationStepQueryNode[] steps = relPath.getPathSteps();
    Name propertyName;
    if (node.getOperation() == QueryConstants.OPERATION_SIMILAR) {
        // this is a bit ugly:
        // use the name of a dummy property because relPath actually
        // references a property. whereas the relPath of the similar
        // operation references a node
        propertyName = NameConstants.JCR_PRIMARYTYPE;
    } else {
        propertyName = steps[steps.length - 1].getNameTest();
    }
    Query query;
    String[] stringValues = new String[1];
    switch(node.getValueType()) {
        case 0:
            // not set: either IS NULL or IS NOT NULL
            break;
        case QueryConstants.TYPE_DATE:
            stringValues[0] = DateField.dateToString(node.getDateValue());
            break;
        case QueryConstants.TYPE_DOUBLE:
            stringValues[0] = DoubleField.doubleToString(node.getDoubleValue());
            break;
        case QueryConstants.TYPE_LONG:
            stringValues[0] = LongField.longToString(node.getLongValue());
            break;
        case QueryConstants.TYPE_STRING:
            if (node.getOperation() == QueryConstants.OPERATION_EQ_GENERAL || node.getOperation() == QueryConstants.OPERATION_EQ_VALUE || node.getOperation() == QueryConstants.OPERATION_NE_GENERAL || node.getOperation() == QueryConstants.OPERATION_NE_VALUE) {
                // only use coercing on non-range operations
                stringValues = getStringValues(propertyName, node.getStringValue());
            } else {
                stringValues[0] = node.getStringValue();
            }
            break;
        case QueryConstants.TYPE_POSITION:
            // ignore position. is handled in the location step
            return null;
        default:
            throw new IllegalArgumentException("Unknown relation type: " + node.getValueType());
    }
    // get property transformation
    final int[] transform = new int[] { TransformConstants.TRANSFORM_NONE };
    node.acceptOperands(new DefaultQueryNodeVisitor() {

        public Object visit(PropertyFunctionQueryNode node, Object data) {
            if (node.getFunctionName().equals(PropertyFunctionQueryNode.LOWER_CASE)) {
                transform[0] = TransformConstants.TRANSFORM_LOWER_CASE;
            } else if (node.getFunctionName().equals(PropertyFunctionQueryNode.UPPER_CASE)) {
                transform[0] = TransformConstants.TRANSFORM_UPPER_CASE;
            }
            return data;
        }
    }, null);
    String field = "";
    try {
        field = resolver.getJCRName(propertyName);
    } catch (NamespaceException e) {
        // should never happen
        exceptions.add(e);
    }
    // support for fn:name()
    if (propertyName.equals(FN_NAME)) {
        if (node.getValueType() != QueryConstants.TYPE_STRING) {
            exceptions.add(new InvalidQueryException("Name function can " + "only be used in conjunction with a string literal"));
            return data;
        }
        if (node.getOperation() == QueryConstants.OPERATION_EQ_VALUE || node.getOperation() == QueryConstants.OPERATION_EQ_GENERAL) {
            // check if string literal is a valid XML Name
            if (XMLChar.isValidName(node.getStringValue())) {
                // parse string literal as JCR Name
                try {
                    Name n = session.getQName(ISO9075.decode(node.getStringValue()));
                    query = new NameQuery(n, indexFormatVersion, nsMappings);
                } catch (NameException e) {
                    exceptions.add(e);
                    return data;
                } catch (NamespaceException e) {
                    exceptions.add(e);
                    return data;
                }
            } else {
                // will never match -> create dummy query
                query = new BooleanQuery();
            }
        } else if (node.getOperation() == QueryConstants.OPERATION_LIKE) {
            // no coercing, see above
            if (stringValues[0].equals("%")) {
                query = new org.apache.lucene.search.MatchAllDocsQuery();
            } else {
                query = new WildcardNameQuery(stringValues[0], transform[0], session, nsMappings, cache);
            }
        } else {
            exceptions.add(new InvalidQueryException("Name function can " + "only be used in conjunction with the following operators: equals, like"));
            return data;
        }
    } else {
        switch(node.getOperation()) {
            // =
            case QueryConstants.OPERATION_EQ_VALUE:
            case QueryConstants.OPERATION_EQ_GENERAL:
                BooleanQuery or = new BooleanQuery();
                for (String value : stringValues) {
                    Term t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, value));
                    Query q;
                    if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE) {
                        q = new CaseTermQuery.Upper(t);
                    } else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE) {
                        q = new CaseTermQuery.Lower(t);
                    } else {
                        q = new JackrabbitTermQuery(t);
                    }
                    or.add(q, Occur.SHOULD);
                }
                query = or;
                if (node.getOperation() == QueryConstants.OPERATION_EQ_VALUE) {
                    query = createSingleValueConstraint(or, field);
                }
                break;
            // >=
            case QueryConstants.OPERATION_GE_VALUE:
            case QueryConstants.OPERATION_GE_GENERAL:
                or = new BooleanQuery();
                for (String value : stringValues) {
                    Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, value));
                    Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, "￿"));
                    or.add(new RangeQuery(lower, upper, true, transform[0], cache), Occur.SHOULD);
                }
                query = or;
                if (node.getOperation() == QueryConstants.OPERATION_GE_VALUE) {
                    query = createSingleValueConstraint(or, field);
                }
                break;
            // >
            case QueryConstants.OPERATION_GT_VALUE:
            case QueryConstants.OPERATION_GT_GENERAL:
                or = new BooleanQuery();
                for (String value : stringValues) {
                    Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, value));
                    Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, "￿"));
                    or.add(new RangeQuery(lower, upper, false, transform[0], cache), Occur.SHOULD);
                }
                query = or;
                if (node.getOperation() == QueryConstants.OPERATION_GT_VALUE) {
                    query = createSingleValueConstraint(or, field);
                }
                break;
            // <=
            case QueryConstants.OPERATION_LE_VALUE:
            case // <=
            QueryConstants.OPERATION_LE_GENERAL:
                or = new BooleanQuery();
                for (String value : stringValues) {
                    Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, ""));
                    Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, value));
                    or.add(new RangeQuery(lower, upper, true, transform[0], cache), Occur.SHOULD);
                }
                query = or;
                if (node.getOperation() == QueryConstants.OPERATION_LE_VALUE) {
                    query = createSingleValueConstraint(query, field);
                }
                break;
            case // LIKE
            QueryConstants.OPERATION_LIKE:
                // no coercing, see above
                if (stringValues[0].equals("%")) {
                    query = Util.createMatchAllQuery(field, indexFormatVersion, cache);
                } else {
                    query = new WildcardQuery(FieldNames.PROPERTIES, field, stringValues[0], transform[0], cache);
                }
                break;
            // <
            case QueryConstants.OPERATION_LT_VALUE:
            case QueryConstants.OPERATION_LT_GENERAL:
                or = new BooleanQuery();
                for (String value : stringValues) {
                    Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, ""));
                    Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, value));
                    or.add(new RangeQuery(lower, upper, false, transform[0], cache), Occur.SHOULD);
                }
                query = or;
                if (node.getOperation() == QueryConstants.OPERATION_LT_VALUE) {
                    query = createSingleValueConstraint(or, field);
                }
                break;
            case // !=
            QueryConstants.OPERATION_NE_VALUE:
                // match nodes with property 'field' that includes svp and mvp
                BooleanQuery notQuery = new BooleanQuery();
                notQuery.add(Util.createMatchAllQuery(field, indexFormatVersion, cache), Occur.SHOULD);
                // exclude all nodes where 'field' has the term in question
                for (String value : stringValues) {
                    Term t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, value));
                    Query q;
                    if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE) {
                        q = new CaseTermQuery.Upper(t);
                    } else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE) {
                        q = new CaseTermQuery.Lower(t);
                    } else {
                        q = new JackrabbitTermQuery(t);
                    }
                    notQuery.add(q, Occur.MUST_NOT);
                }
                // and exclude all nodes where 'field' is multi valued
                notQuery.add(new JackrabbitTermQuery(new Term(FieldNames.MVP, field)), Occur.MUST_NOT);
                query = notQuery;
                break;
            case // !=
            QueryConstants.OPERATION_NE_GENERAL:
                // that's:
                // all nodes with property 'field'
                // minus the nodes that have a single property 'field' that is
                //    not equal to term in question
                // minus the nodes that have a multi-valued property 'field' and
                //    all values are equal to term in question
                notQuery = new BooleanQuery();
                notQuery.add(Util.createMatchAllQuery(field, indexFormatVersion, cache), Occur.SHOULD);
                for (String value : stringValues) {
                    // exclude the nodes that have the term and are single valued
                    Term t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, value));
                    Query svp = new NotQuery(new JackrabbitTermQuery(new Term(FieldNames.MVP, field)));
                    BooleanQuery and = new BooleanQuery();
                    Query q;
                    if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE) {
                        q = new CaseTermQuery.Upper(t);
                    } else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE) {
                        q = new CaseTermQuery.Lower(t);
                    } else {
                        q = new JackrabbitTermQuery(t);
                    }
                    and.add(q, Occur.MUST);
                    and.add(svp, Occur.MUST);
                    notQuery.add(and, Occur.MUST_NOT);
                }
                // todo above also excludes multi-valued properties that contain
                //      multiple instances of only stringValues. e.g. text={foo, foo}
                query = notQuery;
                break;
            case QueryConstants.OPERATION_NULL:
                query = new NotQuery(Util.createMatchAllQuery(field, indexFormatVersion, cache));
                break;
            case QueryConstants.OPERATION_SIMILAR:
                try {
                    NodeId id = hmgr.resolveNodePath(session.getQPath(node.getStringValue()));
                    if (id != null) {
                        query = new SimilarityQuery(id.toString(), analyzer);
                    } else {
                        query = new BooleanQuery();
                    }
                } catch (Exception e) {
                    exceptions.add(e);
                    query = new BooleanQuery();
                }
                break;
            case QueryConstants.OPERATION_NOT_NULL:
                query = Util.createMatchAllQuery(field, indexFormatVersion, cache);
                break;
            case QueryConstants.OPERATION_SPELLCHECK:
                query = Util.createMatchAllQuery(field, indexFormatVersion, cache);
                break;
            default:
                throw new IllegalArgumentException("Unknown relation operation: " + node.getOperation());
        }
    }
    if (steps.length > 1) {
        // child axis in relation
        // elements.length - 1 = property name
        // elements.length - 2 = last child axis name test
        boolean selectParent = true;
        for (int i = steps.length - 2; i >= 0; i--) {
            LocationStepQueryNode step = steps[i];
            Name name = steps[i].getNameTest();
            if (i == steps.length - 2) {
                if (step instanceof DerefQueryNode) {
                    query = createPredicateDeref(query, (DerefQueryNode) step, data);
                    if (steps.length == 2) {
                        selectParent = false;
                    }
                } else if (step != null) {
                    // join name test with property query if there is one
                    if (name != null) {
                        if (!name.equals(PARENT_ELEMENT_NAME)) {
                            Query nameTest = new NameQuery(name, indexFormatVersion, nsMappings);
                            BooleanQuery and = new BooleanQuery();
                            and.add(query, Occur.MUST);
                            and.add(nameTest, Occur.MUST);
                            query = and;
                        } else {
                            // If we're searching the parent, we want to return the child axis,
                            // not the parent because this is part of the predicate. For instance,
                            // if the query is //child[../base], this part of the code is operating
                            // on the "../base" portion. So we want to return all the child nodes
                            // of "base", which will then be matched against the non predicate part.
                            query = new ChildAxisQuery(sharedItemMgr, query, null, indexFormatVersion, nsMappings);
                            selectParent = false;
                        }
                    } else {
                    // otherwise the query can be used as is
                    }
                }
            } else if (name != null && name.equals(PARENT_ELEMENT_NAME)) {
                // We need to select one of the properties if we haven't already.
                if (selectParent) {
                    query = new ParentAxisQuery(query, null, indexFormatVersion, nsMappings);
                    selectParent = false;
                }
                // See the note above on searching parents
                query = new ChildAxisQuery(sharedItemMgr, query, null, indexFormatVersion, nsMappings);
            } else {
                if (step != null) {
                    query = new ParentAxisQuery(query, name, indexFormatVersion, nsMappings);
                } else {
                    throw new UnsupportedOperationException();
                }
            }
        }
        // finally select the parent of the selected nodes
        if (selectParent) {
            query = new ParentAxisQuery(query, null, indexFormatVersion, nsMappings);
        }
    }
    return query;
}
Also used : PropertyFunctionQueryNode(org.apache.jackrabbit.spi.commons.query.PropertyFunctionQueryNode) DerefQueryNode(org.apache.jackrabbit.spi.commons.query.DerefQueryNode) Name(org.apache.jackrabbit.spi.Name) PathQueryNode(org.apache.jackrabbit.spi.commons.query.PathQueryNode) DefaultQueryNodeVisitor(org.apache.jackrabbit.spi.commons.query.DefaultQueryNodeVisitor) LocationStepQueryNode(org.apache.jackrabbit.spi.commons.query.LocationStepQueryNode) Term(org.apache.lucene.index.Term) NameException(org.apache.jackrabbit.spi.commons.conversion.NameException) ParseException(org.apache.lucene.queryParser.ParseException) RepositoryException(javax.jcr.RepositoryException) NamespaceException(javax.jcr.NamespaceException) InvalidQueryException(javax.jcr.query.InvalidQueryException) NameException(org.apache.jackrabbit.spi.commons.conversion.NameException) NodeId(org.apache.jackrabbit.core.id.NodeId) NamespaceException(javax.jcr.NamespaceException) InvalidQueryException(javax.jcr.query.InvalidQueryException)

Example 32 with InvalidQueryException

use of javax.jcr.query.InvalidQueryException in project jackrabbit by apache.

the class ChildNodeTest method testSyntacticallyInvalidPath.

public void testSyntacticallyInvalidPath() throws RepositoryException {
    String invalidPath = testRoot + "/" + nodeName1 + "[";
    try {
        Query q = qf.createQuery(qf.selector(testNodeType, "s"), qf.childNode("s", invalidPath), null, null);
        q.execute();
        fail("ChildNode with syntactically invalid path argument must throw InvalidQueryException");
    } catch (InvalidQueryException e) {
    // expected
    }
    try {
        String stmt = "SELECT * FROM [" + testNodeType + "] AS s WHERE " + "ISCHILDNODE(s, [" + invalidPath + "])";
        qm.createQuery(stmt, Query.JCR_SQL2).execute();
        fail("ISCHILDNODE() with syntactically invalid path argument must throw InvalidQueryException");
    } catch (InvalidQueryException e) {
    // expected
    }
}
Also used : Query(javax.jcr.query.Query) InvalidQueryException(javax.jcr.query.InvalidQueryException)

Example 33 with InvalidQueryException

use of javax.jcr.query.InvalidQueryException in project jackrabbit by apache.

the class SelectorTest method testUnknownNodeType.

public void testUnknownNodeType() throws RepositoryException {
    NodeTypeManager ntMgr = superuser.getWorkspace().getNodeTypeManager();
    String ntName = testNodeType;
    for (; ; ) {
        try {
            ntMgr.getNodeType(ntName);
            ntName += "x";
        } catch (NoSuchNodeTypeException e) {
            break;
        }
    }
    try {
        qf.createQuery(qf.selector(ntName, "s"), null, null, null).execute();
        fail("Selector with unknown node type must throw InvalidQueryException");
    } catch (InvalidQueryException e) {
    // expected
    }
    try {
        String stmt = "SELECT * FROM [" + ntName + "] AS nt";
        qm.createQuery(stmt, Query.JCR_SQL2).execute();
        fail("Selector with unknown node type must throw InvalidQueryException");
    } catch (InvalidQueryException e) {
    // expected
    }
}
Also used : NodeTypeManager(javax.jcr.nodetype.NodeTypeManager) InvalidQueryException(javax.jcr.query.InvalidQueryException) NoSuchNodeTypeException(javax.jcr.nodetype.NoSuchNodeTypeException)

Example 34 with InvalidQueryException

use of javax.jcr.query.InvalidQueryException in project jackrabbit by apache.

the class SameNodeTest method testNotASelectorName.

public void testNotASelectorName() throws RepositoryException {
    try {
        Query q = qf.createQuery(qf.selector(testNodeType, "s"), qf.sameNode("x", testRoot), null, null);
        q.execute();
        fail("SameNode with an invalid selector name must throw InvalidQueryException");
    } catch (InvalidQueryException e) {
    // expected
    }
    try {
        String stmt = "SELECT * FROM [" + testNodeType + "] AS s " + "WHERE ISSAMENODE(x, [" + testRoot + "]";
        qm.createQuery(stmt, Query.JCR_SQL2).execute();
        fail("ISSAMENODE with an invalid selector name must throw InvalidQueryException");
    } catch (InvalidQueryException e) {
    // expected
    }
}
Also used : Query(javax.jcr.query.Query) InvalidQueryException(javax.jcr.query.InvalidQueryException)

Example 35 with InvalidQueryException

use of javax.jcr.query.InvalidQueryException in project jackrabbit by apache.

the class SameNodeTest method testSyntacticallyInvalidPath.

public void testSyntacticallyInvalidPath() throws RepositoryException {
    String invalidPath = testRoot + "/" + nodeName1 + "[";
    try {
        Query q = qf.createQuery(qf.selector(testNodeType, "s"), qf.sameNode("s", invalidPath), null, null);
        q.execute();
        fail("SameNode with syntactically invalid path argument must throw InvalidQueryException");
    } catch (InvalidQueryException e) {
    // expected
    }
    try {
        String stmt = "SELECT * FROM [" + testNodeType + "] AS s " + "WHERE ISSAMENODE(s, [" + invalidPath + "]";
        qm.createQuery(stmt, Query.JCR_SQL2).execute();
        fail("ISSAMENODE() with syntactically invalid path argument must throw InvalidQueryException");
    } catch (InvalidQueryException e) {
    // expected
    }
}
Also used : Query(javax.jcr.query.Query) InvalidQueryException(javax.jcr.query.InvalidQueryException)

Aggregations

InvalidQueryException (javax.jcr.query.InvalidQueryException)50 Value (javax.jcr.Value)15 Query (javax.jcr.query.Query)13 NamespaceException (javax.jcr.NamespaceException)9 Name (org.apache.jackrabbit.spi.Name)7 LocationStepQueryNode (org.apache.jackrabbit.spi.commons.query.LocationStepQueryNode)6 PathQueryNode (org.apache.jackrabbit.spi.commons.query.PathQueryNode)6 RepositoryException (javax.jcr.RepositoryException)5 Constraint (javax.jcr.query.qom.Constraint)5 IllegalNameException (org.apache.jackrabbit.spi.commons.conversion.IllegalNameException)5 NameException (org.apache.jackrabbit.spi.commons.conversion.NameException)5 PropertyFunctionQueryNode (org.apache.jackrabbit.spi.commons.query.PropertyFunctionQueryNode)5 RelationQueryNode (org.apache.jackrabbit.spi.commons.query.RelationQueryNode)5 Path (org.apache.jackrabbit.spi.Path)4 DerefQueryNode (org.apache.jackrabbit.spi.commons.query.DerefQueryNode)4 TextsearchQueryNode (org.apache.jackrabbit.spi.commons.query.TextsearchQueryNode)4 Session (javax.jcr.Session)3 QueryObjectModel (javax.jcr.query.qom.QueryObjectModel)3 NAryQueryNode (org.apache.jackrabbit.spi.commons.query.NAryQueryNode)3 NodeTypeQueryNode (org.apache.jackrabbit.spi.commons.query.NodeTypeQueryNode)3