You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2006/03/10 15:31:07 UTC
svn commit: r384804 - in /incubator/jackrabbit/trunk/jackrabbit/src:
main/java/org/apache/jackrabbit/core/query/lucene/
main/java/org/apache/jackrabbit/core/query/xpath/
test/java/org/apache/jackrabbit/core/query/
Author: mreutegg
Date: Fri Mar 10 06:31:05 2006
New Revision: 384804
URL: http://svn.apache.org/viewcvs?rev=384804&view=rev
Log:
JCR-338: Query Builder and jcr:deref problem. Can't add predicate after jcr:deref
Added:
incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/DerefTest.java (with props)
Modified:
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/DerefQuery.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/SimpleNode.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java
incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/TestAll.java
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/DerefQuery.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/DerefQuery.java?rev=384804&r1=384803&r2=384804&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/DerefQuery.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/DerefQuery.java Fri Mar 10 06:31:05 2006
@@ -275,9 +275,13 @@
}
// retrieve uuids of target nodes
+ String prefix = FieldNames.createNamedValue(refProperty, "");
for (int i = hits.nextSetBit(0); i >= 0; i = hits.nextSetBit(i + 1)) {
String[] values = reader.document(i).getValues(FieldNames.PROPERTIES);
- String prefix = FieldNames.createNamedValue(refProperty, "");
+ if (values == null) {
+ // no reference properties at all on this node
+ continue;
+ }
for (int v = 0; v < values.length; v++) {
if (values[v].startsWith(prefix)) {
uuids.add(values[v].substring(prefix.length()));
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java?rev=384804&r1=384803&r2=384804&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java Fri Mar 10 06:31:05 2006
@@ -508,18 +508,37 @@
if (context == null) {
exceptions.add(new IllegalArgumentException("Unsupported query"));
}
+
try {
String refProperty = node.getRefProperty().toJCRName(nsMappings);
String nameTest = null;
if (node.getNameTest() != null) {
nameTest = node.getNameTest().toJCRName(nsMappings);
}
- return new DerefQuery(context, refProperty, nameTest);
+
+ if (node.getIncludeDescendants()) {
+ Query refPropQuery = new MatchAllQuery(refProperty);
+ context = new DescendantSelfAxisQuery(context, refPropQuery, false);
+ }
+
+ context = new DerefQuery(context, refProperty, nameTest);
+
+ // attach predicates
+ Object[] predicates = node.acceptOperands(this, data);
+ if (predicates.length > 0) {
+ BooleanQuery andQuery = new BooleanQuery();
+ for (int i = 0; i < predicates.length; i++) {
+ andQuery.add((Query) predicates[i], true, false);
+ }
+ andQuery.add(context, true, false);
+ context = andQuery;
+ }
+
} catch (NoPrefixDeclaredException e) {
// should never happen
exceptions.add(e);
}
- // fallback in case of exception
+
return context;
}
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/SimpleNode.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/SimpleNode.java?rev=384804&r1=384803&r2=384804&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/SimpleNode.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/SimpleNode.java Fri Mar 10 06:31:05 2006
@@ -86,7 +86,7 @@
public Object childrenAccept(XPathVisitor visitor, Object data) {
if (children != null) {
for (int i = 0; i < children.length; ++i) {
- children[i].jjtAccept(visitor, data);
+ data = children[i].jjtAccept(visitor, data);
}
}
return data;
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java?rev=384804&r1=384803&r2=384804&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java Fri Mar 10 06:31:05 2006
@@ -324,7 +324,7 @@
case JJTSTEPEXPR:
if (isAttributeAxis(node)) {
if (queryNode.getType() == QueryNode.TYPE_RELATION
- || queryNode.getType() == QueryNode.TYPE_DEREF
+ || (queryNode.getType() == QueryNode.TYPE_DEREF && ((DerefQueryNode) queryNode).getRefProperty() == null)
|| queryNode.getType() == QueryNode.TYPE_ORDER
|| queryNode.getType() == QueryNode.TYPE_PATH
|| queryNode.getType() == QueryNode.TYPE_TEXTSEARCH) {
@@ -350,7 +350,7 @@
}
} else {
if (queryNode.getType() == QueryNode.TYPE_PATH) {
- queryNode = createLocationStep(node, (NAryQueryNode) queryNode);
+ createLocationStep(node, (NAryQueryNode) queryNode);
} else if (queryNode.getType() == QueryNode.TYPE_TEXTSEARCH) {
// ignore
} else {
@@ -457,6 +457,14 @@
specs[specs.length - 1].setAscending(false);
}
break;
+ case JJTPREDICATELIST:
+ if (queryNode.getType() == QueryNode.TYPE_PATH) {
+ // switch to last location
+ QueryNode[] operands = ((PathQueryNode) queryNode).getOperands();
+ queryNode = operands[operands.length - 1];
+ }
+ node.childrenAccept(this, queryNode);
+ break;
default:
// per default traverse
node.childrenAccept(this, queryNode);
@@ -476,16 +484,16 @@
*/
private LocationStepQueryNode createLocationStep(SimpleNode node, NAryQueryNode parent) {
LocationStepQueryNode queryNode = null;
- boolean descenant = false;
+ boolean descendant = false;
Node p = node.jjtGetParent();
for (int i = 0; i < p.jjtGetNumChildren(); i++) {
SimpleNode c = (SimpleNode) p.jjtGetChild(i);
if (c == node) {
- queryNode = new LocationStepQueryNode(parent, null, descenant);
+ queryNode = new LocationStepQueryNode(parent, null, descendant);
parent.addOperand(queryNode);
break;
}
- descenant = (c.getId() == JJTSLASHSLASH
+ descendant = (c.getId() == JJTSLASHSLASH
|| c.getId() == JJTROOTDESCENDANTS);
}
@@ -781,6 +789,14 @@
} else if (JCR_DEREF.toJCRName(resolver).equals(fName)) {
// check number of arguments
if (node.jjtGetNumChildren() == 3) {
+ boolean descendant = false;
+ if (queryNode.getType() == QueryNode.TYPE_LOCATION) {
+ LocationStepQueryNode loc = (LocationStepQueryNode) queryNode;
+ // remember if descendant axis
+ descendant = loc.getIncludeDescendants();
+ queryNode = loc.getParent();
+ ((NAryQueryNode) queryNode).removeOperand(loc);
+ }
if (queryNode.getType() == QueryNode.TYPE_PATH) {
PathQueryNode pathNode = (PathQueryNode) queryNode;
DerefQueryNode derefNode = new DerefQueryNode(pathNode, null, false);
@@ -811,6 +827,20 @@
} else {
exceptions.add(new InvalidQueryException("Wrong second argument type for jcr:like"));
}
+
+ // check if descendant
+ if (!descendant) {
+ Node p = node.jjtGetParent();
+ for (int i = 0; i < p.jjtGetNumChildren(); i++) {
+ SimpleNode c = (SimpleNode) p.jjtGetChild(i);
+ if (c == node) {
+ break;
+ }
+ descendant = (c.getId() == JJTSLASHSLASH
+ || c.getId() == JJTROOTDESCENDANTS);
+ }
+ }
+ derefNode.setIncludeDescendants(descendant);
pathNode.addPathStep(derefNode);
} else {
exceptions.add(new InvalidQueryException("Unsupported location for jcr:deref()"));
Added: incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/DerefTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/DerefTest.java?rev=384804&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/DerefTest.java (added)
+++ incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/DerefTest.java Fri Mar 10 06:31:05 2006
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.query;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/**
+ * Tests the jcr:deref() function.
+ */
+public class DerefTest extends AbstractQueryTest {
+
+ /**
+ * Test nodes.
+ */
+ private Node andrew, bill, carl, daren, eric, frank;
+
+ /**
+ * Test nodes.
+ */
+ private Node sun, microsoft, ibm;
+
+ /**
+ * Sets up the following structure:
+ * <pre>
+ * + people
+ * + andrew (worksfor -> company/sun)
+ * + bill (worksfor -> company/ibm)
+ * + carl (worksfor -> company/microsoft)
+ * + daren (worksfor -> company/ibm)
+ * + eric (worksfor -> company/sun)
+ * + frank (worksfor -> company/microsoft)
+ * + company
+ * + sun
+ * + microsoft
+ * + ibm
+ * </pre>
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ Node people = testRootNode.addNode("people");
+ Node company = testRootNode.addNode("company");
+
+ sun = company.addNode("sun");
+ sun.addMixin(mixReferenceable);
+ sun.setProperty("ceo", "McNealy");
+ microsoft = company.addNode("microsoft");
+ microsoft.addMixin(mixReferenceable);
+ microsoft.setProperty("ceo", "Ballmer");
+ ibm = company.addNode("ibm");
+ ibm.addMixin(mixReferenceable);
+ ibm.setProperty("ceo", "Palmisano");
+
+ andrew = people.addNode("andrew");
+ andrew.setProperty("worksfor", sun);
+ bill = andrew.addNode("bill");
+ bill.setProperty("worksfor", ibm);
+ carl = people.addNode("carl");
+ carl.setProperty("worksfor", microsoft);
+ daren = carl.addNode("daren");
+ daren.setProperty("worksfor", ibm);
+ eric = daren.addNode("eric");
+ eric.setProperty("worksfor", sun);
+ frank = people.addNode("frank");
+ frank.setProperty("worksfor", microsoft);
+
+ testRootNode.save();
+ }
+
+ /**
+ * Tests various XPath queries with jcr:deref() function.
+ */
+ public void testDeref() throws RepositoryException {
+ executeXPathQuery(testPath + "/people/jcr:deref(@worksfor, '*')",
+ new Node[]{});
+
+ executeXPathQuery(testPath + "/people/*/jcr:deref(@worksfor, '*')",
+ new Node[]{sun, microsoft});
+
+ executeXPathQuery(testPath + "/people/*/*/jcr:deref(@worksfor, '*')",
+ new Node[]{ibm});
+
+ executeXPathQuery(testPath + "/people//jcr:deref(@worksfor, '*')",
+ new Node[]{sun, ibm, microsoft});
+
+ executeXPathQuery(testPath + "/people/carl//jcr:deref(@worksfor, '*')",
+ new Node[]{sun, ibm});
+
+ executeXPathQuery(testPath + "/people//jcr:deref(@worksfor, 'sun')",
+ new Node[]{sun});
+
+ executeXPathQuery(testPath + "/people//jcr:deref(@worksfor, '*')[@ceo = 'McNealy']",
+ new Node[]{sun});
+
+ executeXPathQuery(testPath + "/people/*/jcr:deref(@worksfor, '*')[jcr:contains(.,'ballmer')]",
+ new Node[]{microsoft});
+ }
+}
Propchange: incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/DerefTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/TestAll.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/TestAll.java?rev=384804&r1=384803&r2=384804&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/TestAll.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/query/TestAll.java Fri Mar 10 06:31:05 2006
@@ -43,6 +43,7 @@
suite.addTestSuite(XPathAxisTest.class);
suite.addTestSuite(SkipDeletedNodesTest.class);
suite.addTestSuite(MixinTest.class);
+ suite.addTestSuite(DerefTest.class);
// exclude long running tests per default
//suite.addTestSuite(MassiveRangeTest.class);