You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2012/02/28 16:57:39 UTC

svn commit: r1294706 - in /jackrabbit/sandbox/jackrabbit-microkernel/src: main/java/org/apache/jackrabbit/query/qom/ main/java/org/apache/jackrabbit/query/qom/tree/ test/java/org/apache/jackrabbit/query/ test/resources/

Author: thomasm
Date: Tue Feb 28 15:57:38 2012
New Revision: 1294706

URL: http://svn.apache.org/viewvc?rev=1294706&view=rev
Log:
Query implementation (WIP)

Added:
    jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt
Modified:
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/AndImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/BindVariableValueImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ChildNodeImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ComparisonImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ConstraintImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/DescendantNodeImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/FullTextSearchImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/JoinImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/NotImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/OrImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/PropertyExistenceImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/PropertyValueImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/QOMNode.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SameNodeImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SelectorImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SourceImpl.java
    jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/QueryTest.java

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java Tue Feb 28 15:57:38 2012
@@ -43,7 +43,6 @@ import org.apache.jackrabbit.query.qom.t
 import org.apache.jackrabbit.query.qom.tree.SameNodeJoinConditionImpl;
 import org.apache.jackrabbit.query.qom.tree.SelectorImpl;
 import org.apache.jackrabbit.query.qom.tree.SourceImpl;
-import org.apache.jackrabbit.query.reader.Cursor;
 
 /**
  * The implementation of the corresponding JCR interface. Lifecycle: use the
@@ -54,7 +53,7 @@ public class QueryObjectModelImpl implem
 
     private MicroKernel mk;
     final SourceImpl source;
-    private final ConstraintImpl constraint;
+    final ConstraintImpl constraint;
     private final OrderingImpl[] orderings;
     private final ColumnImpl[] columns;
     final HashMap<String, Value> bindVariableMap = new HashMap<String, Value>();
@@ -74,86 +73,108 @@ public class QueryObjectModelImpl implem
 
     public void init() {
 
+        final QueryObjectModelImpl query = this;
+
         new QOMTreeVisitor() {
 
             @Override
             public boolean visit(BindVariableValueImpl node) {
+                node.setQuery(query);
                 bindVariableMap.put(node.getBindVariableName(), null);
                 return true;
             }
 
             @Override
             public boolean visit(ChildNodeImpl node) {
+                node.setQuery(query);
                 return true;
             }
 
             @Override
             public boolean visit(ChildNodeJoinConditionImpl node) {
+                node.setQuery(query);
                 return true;
             }
 
             @Override
             public boolean visit(ColumnImpl node) {
+                node.setQuery(query);
                 return true;
             }
 
             @Override
             public boolean visit(DescendantNodeImpl node) {
+                node.setQuery(query);
+                node.bindSelector(source);
                 return true;
             }
 
             @Override
             public boolean visit(DescendantNodeJoinConditionImpl node) {
+                node.setQuery(query);
                 return true;
             }
 
             @Override
             public boolean visit(EquiJoinConditionImpl node) {
+                node.setQuery(query);
                 return true;
             }
 
             @Override
             public boolean visit(FullTextSearchScoreImpl node) {
+                node.setQuery(query);
                 return true;
             }
 
             @Override
             public boolean visit(LiteralImpl node) {
+                node.setQuery(query);
                 return true;
             }
 
             @Override
             public boolean visit(NodeLocalNameImpl node) {
+                node.setQuery(query);
                 return true;
             }
 
             @Override
             public boolean visit(NodeNameImpl node) {
+                node.setQuery(query);
                 return true;
             }
 
             @Override
             public boolean visit(PropertyExistenceImpl node) {
+                node.setQuery(query);
+                node.bindSelector(source);
                 return true;
             }
 
             @Override
             public boolean visit(PropertyValueImpl node) {
+                node.setQuery(query);
+                node.bindSelector(source);
                 return true;
             }
 
             @Override
             public boolean visit(SameNodeImpl node) {
+                node.setQuery(query);
+                node.bindSelector(source);
                 return true;
             }
 
             @Override
             public boolean visit(SameNodeJoinConditionImpl node) {
+                node.setQuery(query);
                 return true;
             }
 
             @Override
             public boolean visit(SelectorImpl node) {
+                node.setQuery(query);
                 return true;
             }
 
@@ -243,23 +264,32 @@ public class QueryObjectModelImpl implem
     class ResultIterator implements Iterator<String> {
 
         private final String revisionId;
-        private Cursor cursor;
         private String current;
-        private boolean end;
+        private boolean started, end;
 
         ResultIterator(String revisionId) {
             this.revisionId = revisionId;
         }
 
         private void fetchNext() {
-            if (cursor == null) {
-                cursor = source.execute(revisionId);
+            if (end) {
+                return;
             }
-            if (cursor.next()) {
-                current = cursor.currentPath();
-            } else {
-                current = null;
-                end = true;
+            if (!started) {
+                source.execute(revisionId);
+                started = true;
+            }
+            while (true) {
+                if (source.next()) {
+                    if (constraint == null || constraint.evaluate()) {
+                        current = source.currentPath();
+                        break;
+                    }
+                } else {
+                    current = null;
+                    end = true;
+                    break;
+                }
             }
         }
 

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/AndImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/AndImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/AndImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/AndImpl.java Tue Feb 28 15:57:38 2012
@@ -18,7 +18,6 @@
  */
 package org.apache.jackrabbit.query.qom.tree;
 
-import javax.jcr.RepositoryException;
 import javax.jcr.query.qom.And;
 
 /**
@@ -41,7 +40,8 @@ public class AndImpl extends ConstraintI
         return constraint2;
     }
 
-    boolean evaluate() throws RepositoryException {
+    @Override
+    public boolean evaluate() {
         return constraint1.evaluate() && constraint2.evaluate();
     }
 

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/BindVariableValueImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/BindVariableValueImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/BindVariableValueImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/BindVariableValueImpl.java Tue Feb 28 15:57:38 2012
@@ -20,6 +20,7 @@ package org.apache.jackrabbit.query.qom.
 
 import javax.jcr.Value;
 import javax.jcr.query.qom.BindVariableValue;
+import org.apache.jackrabbit.query.qom.QueryObjectModelImpl;
 
 /**
  * The implementation of the corresponding JCR interface.

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ChildNodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ChildNodeImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ChildNodeImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ChildNodeImpl.java Tue Feb 28 15:57:38 2012
@@ -18,7 +18,6 @@
  */
 package org.apache.jackrabbit.query.qom.tree;
 
-import javax.jcr.RepositoryException;
 import javax.jcr.query.qom.ChildNode;
 
 
@@ -53,7 +52,7 @@ public class ChildNodeImpl extends Const
     }
 
     @Override
-    boolean evaluate() throws RepositoryException {
+    public boolean evaluate() {
         // TODO Auto-generated method stub
         return false;
     }

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ComparisonImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ComparisonImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ComparisonImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ComparisonImpl.java Tue Feb 28 15:57:38 2012
@@ -19,6 +19,7 @@
 package org.apache.jackrabbit.query.qom.tree;
 
 import javax.jcr.RepositoryException;
+import javax.jcr.Value;
 import javax.jcr.query.qom.Comparison;
 
 /**
@@ -48,21 +49,33 @@ public class ComparisonImpl extends Cons
         return operand2;
     }
 
-    boolean evaluate() throws RepositoryException {
-        switch (operator) {
-        case EQ:
-            return operand1.currentValue().equals(operand2.currentValue());
-        case GE:
-        case GT:
-        case LE:
-        case LIKE:
-        case LT:
-            return operand1.currentValue() .equals(operand2.currentValue());
-        case NE:
-            return !operand1.currentValue().equals(operand2.currentValue());
+    @Override
+    public boolean evaluate() {
+        try {
+            Value v1 = operand1.currentValue();
+            Value v2 = operand2.currentValue();
+            if (v1 == null || v2 == null) {
+                // TODO comparison: what about (null <> x) ?
+                return false;
+            }
+            switch (operator) {
+            case EQ:
+                return v1.equals(v2);
+            case GE:
+            case GT:
+            case LE:
+            case LIKE:
+            case LT:
+                return operand1.currentValue() .equals(operand2.currentValue());
+            case NE:
+                return !operand1.currentValue().equals(operand2.currentValue());
+            }
+            // TODO Auto-generated method stub
+            return false;
+        } catch (RepositoryException e) {
+            // TODO exception handling
+            throw new RuntimeException(e);
         }
-        // TODO Auto-generated method stub
-        return false;
     }
 
     @Override

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ConstraintImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ConstraintImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ConstraintImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ConstraintImpl.java Tue Feb 28 15:57:38 2012
@@ -16,7 +16,6 @@
  */
 package org.apache.jackrabbit.query.qom.tree;
 
-import javax.jcr.RepositoryException;
 import javax.jcr.query.qom.Constraint;
 
 /**
@@ -24,6 +23,6 @@ import javax.jcr.query.qom.Constraint;
  */
 public abstract class ConstraintImpl extends QOMNode implements Constraint {
 
-    abstract boolean evaluate() throws RepositoryException;
+    public abstract boolean evaluate();
 
 }

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/DescendantNodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/DescendantNodeImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/DescendantNodeImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/DescendantNodeImpl.java Tue Feb 28 15:57:38 2012
@@ -43,7 +43,8 @@ public class DescendantNodeImpl extends 
         return ancestorPath;
     }
 
-    boolean evaluate() {
+    @Override
+    public boolean evaluate() {
         return PathUtils.isAncestor(ancestorPath, selector.currentNode().getPath());
     }
 
@@ -56,4 +57,11 @@ public class DescendantNodeImpl extends 
         return "ISDESCENDANTNODE(" + getSelectorName() + ", " + quotePath(ancestorPath) + ')';
     }
 
+    public void bindSelector(SourceImpl source) {
+        selector = source.getSelector(selectorName);
+        if (selector == null) {
+            throw new RuntimeException("Unknown selector: " + selectorName);
+        }
+    }
+
 }

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/FullTextSearchImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/FullTextSearchImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/FullTextSearchImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/FullTextSearchImpl.java Tue Feb 28 15:57:38 2012
@@ -18,7 +18,6 @@
  */
 package org.apache.jackrabbit.query.qom.tree;
 
-import javax.jcr.RepositoryException;
 import javax.jcr.query.qom.FullTextSearch;
 
 /**
@@ -72,7 +71,7 @@ public class FullTextSearchImpl extends 
     }
 
     @Override
-    boolean evaluate() throws RepositoryException {
+    public boolean evaluate() {
         // TODO Auto-generated method stub
         return false;
     }

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/JoinImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/JoinImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/JoinImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/JoinImpl.java Tue Feb 28 15:57:38 2012
@@ -88,4 +88,13 @@ public class JoinImpl extends SourceImpl
         }
     }
 
+    @Override
+    public SelectorImpl getSelector(String selectorName) {
+        SelectorImpl s = left.getSelector(selectorName);
+        if (s == null) {
+            s = right.getSelector(selectorName);
+        }
+        return s;
+    }
+
 }

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/NotImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/NotImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/NotImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/NotImpl.java Tue Feb 28 15:57:38 2012
@@ -18,7 +18,6 @@
  */
 package org.apache.jackrabbit.query.qom.tree;
 
-import javax.jcr.RepositoryException;
 import javax.jcr.query.qom.Not;
 
 /**
@@ -36,7 +35,8 @@ public class NotImpl extends ConstraintI
         return constraint;
     }
 
-    boolean evaluate() throws RepositoryException {
+    @Override
+    public boolean evaluate() {
         return !constraint.evaluate();
     }
 

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/OrImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/OrImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/OrImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/OrImpl.java Tue Feb 28 15:57:38 2012
@@ -18,7 +18,6 @@
  */
 package org.apache.jackrabbit.query.qom.tree;
 
-import javax.jcr.RepositoryException;
 import javax.jcr.query.qom.Or;
 
 /**
@@ -42,7 +41,8 @@ public class OrImpl extends ConstraintIm
         return constraint2;
     }
 
-    boolean evaluate() throws RepositoryException {
+    @Override
+    public boolean evaluate() {
         return constraint1.evaluate() || constraint2.evaluate();
     }
 

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/PropertyExistenceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/PropertyExistenceImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/PropertyExistenceImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/PropertyExistenceImpl.java Tue Feb 28 15:57:38 2012
@@ -42,7 +42,8 @@ public class PropertyExistenceImpl exten
         return selectorName;
     }
 
-    boolean evaluate() {
+    @Override
+    public boolean evaluate() {
         return selector.currentNode().hasProperty(propertyName);
     }
 
@@ -56,4 +57,11 @@ public class PropertyExistenceImpl exten
         return getSelectorName() + '.' + propertyName + " IS NOT NULL";
     }
 
+    public void bindSelector(SourceImpl source) {
+        selector = source.getSelector(selectorName);
+        if (selector == null) {
+            throw new RuntimeException("Unknown selector: " + selectorName);
+        }
+    }
+
 }

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/PropertyValueImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/PropertyValueImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/PropertyValueImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/PropertyValueImpl.java Tue Feb 28 15:57:38 2012
@@ -20,6 +20,8 @@ package org.apache.jackrabbit.query.qom.
 
 import javax.jcr.Value;
 import javax.jcr.query.qom.PropertyValue;
+import org.apache.jackrabbit.mk.json.JsopTokenizer;
+import org.apache.jackrabbit.mk.simple.NodeImpl;
 
 /**
  * The implementation of the corresponding JCR interface.
@@ -55,8 +57,21 @@ public class PropertyValueImpl extends D
 
     @Override
     Value currentValue() {
-        String value = selector.currentNode().getProperty(propertyName);
+        NodeImpl n = selector.currentNode();
+        String value = n.getProperty(propertyName);
+        if (value == null) {
+            return null;
+        }
+        // TODO data type mapping
+        value = JsopTokenizer.decodeQuoted(value);
         return query.getValueFactory().createValue(value);
     }
 
+    public void bindSelector(SourceImpl source) {
+        selector = source.getSelector(selectorName);
+        if (selector == null) {
+            throw new RuntimeException("Unknown selector: " + selectorName);
+        }
+    }
+
 }

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/QOMNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/QOMNode.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/QOMNode.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/QOMNode.java Tue Feb 28 15:57:38 2012
@@ -40,5 +40,9 @@ abstract class QOMNode {
         return '[' + path + ']';
     }
 
+    public void setQuery(QueryObjectModelImpl query) {
+        this.query = query;
+    }
+
 }
 

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SameNodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SameNodeImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SameNodeImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SameNodeImpl.java Tue Feb 28 15:57:38 2012
@@ -42,7 +42,8 @@ public class SameNodeImpl extends Constr
         return path;
     }
 
-    boolean evaluate() {
+    @Override
+    public boolean evaluate() {
         return selector.currentNode().getPath().equals(path);
     }
 
@@ -55,4 +56,11 @@ public class SameNodeImpl extends Constr
         return "ISSAMENODE(" + getSelectorName() + ", " + quotePath(path) + ')';
     }
 
+    public void bindSelector(SourceImpl source) {
+        selector = source.getSelector(selectorName);
+        if (selector == null) {
+            throw new RuntimeException("Unknown selector: " + selectorName);
+        }
+    }
+
 }

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SelectorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SelectorImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SelectorImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SelectorImpl.java Tue Feb 28 15:57:38 2012
@@ -19,7 +19,6 @@
 package org.apache.jackrabbit.query.qom.tree;
 
 import javax.jcr.query.qom.Selector;
-import org.apache.jackrabbit.mk.simple.NodeImpl;
 import org.apache.jackrabbit.query.qom.QueryObjectModelImpl;
 
 /**
@@ -28,7 +27,6 @@ import org.apache.jackrabbit.query.qom.Q
 public class SelectorImpl extends SourceImpl implements Selector {
 
     private final String nodeTypeName, selectorName;
-    private NodeImpl currentNode;
 
     public SelectorImpl(String nodeTypeName, String selectorName) {
         this.nodeTypeName = nodeTypeName;
@@ -59,8 +57,12 @@ public class SelectorImpl extends Source
 
     }
 
-    public NodeImpl currentNode() {
-        return currentNode;
+    @Override
+    public SelectorImpl getSelector(String selectorName) {
+        if (selectorName.equals(this.selectorName)) {
+            return this;
+        }
+        return null;
     }
 
 }

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SourceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SourceImpl.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SourceImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/SourceImpl.java Tue Feb 28 15:57:38 2012
@@ -20,6 +20,7 @@ package org.apache.jackrabbit.query.qom.
 
 import javax.jcr.query.qom.Source;
 import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.simple.NodeImpl;
 import org.apache.jackrabbit.query.qom.QueryObjectModelImpl;
 import org.apache.jackrabbit.query.reader.Cursor;
 import org.apache.jackrabbit.query.reader.Filter;
@@ -33,6 +34,7 @@ public abstract class SourceImpl extends
     protected boolean join;
     protected boolean outerJoin;
     private NodeReader reader;
+    private Cursor cursor;
 
     public void setQueryConstraint(ConstraintImpl queryConstraint) {
         this.queryConstraint = queryConstraint;
@@ -48,12 +50,26 @@ public abstract class SourceImpl extends
 
     public abstract void init(QueryObjectModelImpl qom);
 
+    public abstract SelectorImpl getSelector(String selectorName);
+
     public void prepare(MicroKernel mk) {
         reader = new TraversingReader(mk);
     }
 
-    public Cursor execute(String revisionId) {
-        return reader.query(new Filter(), revisionId);
+    public void execute(String revisionId) {
+        cursor = reader.query(new Filter(), revisionId);
+    }
+
+    public boolean next() {
+        return cursor.next();
+    }
+
+    public String currentPath() {
+        return cursor.currentPath();
+    }
+
+    public NodeImpl currentNode() {
+        return cursor.currentNode();
     }
 
 }

Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/QueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/QueryTest.java?rev=1294706&r1=1294705&r2=1294706&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/QueryTest.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/query/QueryTest.java Tue Feb 28 15:57:38 2012
@@ -13,35 +13,100 @@
  */
 package org.apache.jackrabbit.query;
 
-import static org.junit.Assert.assertEquals;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
 import java.util.Iterator;
-import javax.jcr.RepositoryException;
 import org.apache.jackrabbit.mk.MicroKernelFactory;
 import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 
 public class QueryTest {
 
+    MicroKernel mk;
+    String head;
+    QueryEngine qe;
+
+    @Before
+    public void setUp() {
+        mk = MicroKernelFactory.getInstance("simple:/target/temp;clear");
+        head = mk.getHeadRevision();
+        qe = QueryEngine.getInstance(mk);
+    }
+
+    @After
+    public void tearDown() {
+        mk.dispose();
+    }
+
     @Test
-    public void simple() throws RepositoryException {
-        MicroKernel mk = MicroKernelFactory.getInstance("simple:/target/temp;clear");
-        String head = mk.getHeadRevision();
-
-        head = mk.commit("/", "+ \"test\": { \"hello\": {}, \"world\": {} }", head, "");
-        head = mk.commit("/", "+ \"test2\": { \"id\":\"1\" }", head, "");
-
-        QueryEngine qe = QueryEngine.getInstance(mk);
-        Iterator<String> list = qe.executeQuery("select * from [nt:base]", null);
-        StringBuilder buff = new StringBuilder();
-        while (list.hasNext()) {
-            buff.append(list.next()).append('\n');
+    public void script() throws Exception {
+        InputStream in = getClass().getClassLoader().getResourceAsStream("queryTest.txt");
+        LineNumberReader r = new LineNumberReader(new InputStreamReader(in));
+        PrintWriter w = new PrintWriter(new OutputStreamWriter(new FileOutputStream("target/queryTest.txt")));
+        boolean errors = false;
+        try {
+            while (true) {
+                String line = r.readLine();
+                if (line == null) {
+                    break;
+                }
+                line = line.trim();
+                if (line.startsWith("#") || line.length() == 0) {
+                    w.println(line);
+                } else if (line.startsWith("select")) {
+                    w.println(line);
+                    Iterator<String> result = qe.executeQuery(line, null);
+                    boolean readEnd = true;
+                    while (result.hasNext()) {
+                        String resultLine = result.next();
+                        w.println(resultLine);
+                        if (readEnd) {
+                            line = r.readLine();
+                            if (line == null) {
+                                errors = true;
+                                readEnd = false;
+                            } else {
+                                line = line.trim();
+                                if (line.length() == 0) {
+                                    errors = true;
+                                    readEnd = false;
+                                } else {
+                                    if (!line.equals(resultLine)) {
+                                        errors = true;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    w.println("");
+                    if (readEnd) {
+                        line = r.readLine();
+                        if (line != null) {
+                            line = line.trim();
+                            if (line.length() > 0) {
+                                errors = true;
+                            }
+                        }
+                    }
+                } else {
+                    w.println(line);
+                    mk.commit("/", line, mk.getHeadRevision(), "");
+                }
+            }
+        } finally {
+            w.close();
+            r.close();
+        }
+        if (errors) {
+            throw new Exception("Results in target/queryTest.txt don't match expected " +
+                    "results in src/test/resources/quersTest.txt; compare the files for details");
         }
-        assertEquals(
-                "/test/hello\n" +
-                "/test/world\n" +
-                "/test\n" +
-                "/test2\n", buff.toString());
-
     }
 
 }

Added: jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt?rev=1294706&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt Tue Feb 28 15:57:38 2012
@@ -0,0 +1,36 @@
+# Syntax:
+# * lines starting with "#" are remarks.
+# * lines starting with "select" are queries, followed by expected results and an empty line
+# * all other lines are are committed into the microkernel (line by line)
+# * new tests are typically be added on top, after the syntax docs
+# * use ascii character only
+
++ "test": { "hello": { "x": "1" }, "world": { "x": "2" } }
++ "test2": { "id":"1", "x": "2" }
+
+select * from [nt:base]
+/test/hello
+/test/world
+/test
+/test2
+
+select * from [nt:base] where id = '1'
+/test2
+
+select * from [nt:base] where id = '1' and x = '2'
+/test2
+
+select * from [nt:base] where id = '1' or x = '2'
+/test/world
+/test2
+
+select * from [nt:base] where not (id = '1' or x = '2')
+/test/hello
+/test
+
+select * from [nt:base] where x is null
+/test
+
+- "test"
+- "test2"
+