Author: thomasm
Date: Tue May 15 08:48:03 2012
New Revision: 1338601

URL: http://svn.apache.org/viewvc?rev=1338601&view=rev
Log:
OAK-28 Query implementation (various changes and fixes)

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/PropertyIndex.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/CoreValueMapper.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElement.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryTest.txt
    
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryResultImpl.java
    
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/RowImpl.java
    
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/qom/QueryObjectModelImpl.java
    
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
    
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/qom/QomTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/Indexer.java
 Tue May 15 08:48:03 2012
@@ -44,7 +44,7 @@ import java.util.Map.Entry;
 public class Indexer implements QueryIndexProvider {
 
     // TODO discuss where to store index config data
-    static final String INDEX_CONFIG_ROOT = "/jcr:system/indexes";
+    public static final String INDEX_CONFIG_ROOT = "/jcr:system/indexes";
 
     private static final boolean DISABLED = 
Boolean.getBoolean("mk.indexDisabled");
 

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/PropertyIndex.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/PropertyIndex.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/PropertyIndex.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/mk/index/PropertyIndex.java
 Tue May 15 08:48:03 2012
@@ -49,7 +49,7 @@ public class PropertyIndex implements In
             return null;
         }
         int index = nodeName.indexOf(':');
-        String propertyName = nodeName.substring(0, index);
+        String propertyName = nodeName.substring(index + 1);
         return new PropertyIndex(indexer, propertyName, unique);
     }
 

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/CoreValueMapper.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/CoreValueMapper.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/CoreValueMapper.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/CoreValueMapper.java
 Tue May 15 08:48:03 2012
@@ -31,7 +31,7 @@ import java.util.Map;
  * CoreValueUtil provides methods to convert {@code CoreValue}s to the JSON
  * representation passed to MicroKernel and vice versa.
  */
-class CoreValueMapper {
+public class CoreValueMapper {
 
     private static final Map<Integer, String> TYPE2HINT = new HashMap<Integer, 
String>();
     private static final Map<String, Integer> HINT2TYPE = new HashMap<String, 
Integer>();

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElement.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElement.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElement.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/AstElement.java
 Tue May 15 08:48:03 2012
@@ -18,7 +18,12 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
+import org.apache.jackrabbit.mk.json.JsopReader;
+import org.apache.jackrabbit.mk.json.JsopTokenizer;
+import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.CoreValueFactory;
 import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.kernel.CoreValueMapper;
 import org.apache.jackrabbit.oak.query.Query;
 
 abstract class AstElement {
@@ -60,10 +65,11 @@ abstract class AstElement {
     }
 
     /**
-     * Calculate the session local path (the path excluding the workspace 
name).
+     * Calculate the session local path (the path excluding the workspace name)
+     * if possible.
      *
      * @param path the absolute path
-     * @return the session local path
+     * @return the session local path, or null if not within this workspace
      */
     protected String getLocalPath(String path) {
         String workspaceName = query.getWorkspaceName();
@@ -71,7 +77,27 @@ abstract class AstElement {
             return path;
         }
         String prefix = PathUtils.concat("/", workspaceName);
-        return PathUtils.concat("/", PathUtils.relativize(prefix, path));
+        if (path.startsWith(prefix)) {
+            return PathUtils.concat("/", PathUtils.relativize(prefix, path));
+        }
+        return null;
+    }
+
+    /**
+     * Convert the JSON property value to a core value.
+     *
+     * @param propertyValue JSON property value
+     * @return the core value
+     */
+    protected CoreValue getCoreValue(String propertyValue) {
+        // TODO data type mapping
+        CoreValueFactory vf = query.getValueFactory();
+        JsopReader r = new JsopTokenizer(propertyValue);
+        if (r.matches('[')) {
+            // TODO support arrays, but only for comparisons
+            throw new IllegalArgumentException("Arrays are currently not 
supported: " + propertyValue);
+        }
+        return CoreValueMapper.fromJsopReader(r, vf);
     }
 
 }

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ChildNodeImpl.java
 Tue May 15 08:48:03 2012
@@ -62,6 +62,10 @@ public class ChildNodeImpl extends Const
     public boolean evaluate() {
         String p = selector.currentPath();
         String local = getLocalPath(p);
+        if (local == null) {
+            // not a local path
+            return false;
+        }
         // the parent of the root is the root,
         // so we need to special case this
         return !PathUtils.denotesRoot(local) && 
PathUtils.getParentPath(local).equals(parentPath);

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ComparisonImpl.java
 Tue May 15 08:48:03 2012
@@ -18,6 +18,9 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import javax.jcr.PropertyType;
 import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.api.CoreValueFactory;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
@@ -48,28 +51,96 @@ public class ComparisonImpl extends Cons
 
     @Override
     public boolean evaluate() {
+        // JCR 2.0 spec, 6.7.16 Comparison:
+        // "operand1 may evaluate to an array of values"
+        // TODO support arrays
         CoreValue v1 = operand1.currentValue();
+        // "operand2 always evaluates to a scalar value"
         CoreValue v2 = operand2.currentValue();
         if (v1 == null || v2 == null) {
             // TODO comparison: what about (null <> x) ?
             return false;
         }
+        if (v1.getType() != v2.getType()) {
+            // "the value of operand2 is converted to the
+            // property type of the value of operand1"
+            v2 = convert(query.getValueFactory(), v2, v1.getType());
+        }
         switch (operator) {
         case EQUAL:
             return v1.equals(v2);
         case GREATER_OR_EQUAL:
+            return v1.compareTo(v2) >= 0;
         case GREATER_THAN:
+            return v1.compareTo(v2) > 0;
         case LESS_OR_EQUAL:
+            return v1.compareTo(v2) <= 0;
         case LESS_THAN:
-            return operand1.currentValue().equals(operand2.currentValue());
+            return v1.compareTo(v2) < 0;
         case NOT_EQUAL:
-            return !operand1.currentValue().equals(operand2.currentValue());
+            return !v1.equals(v2);
         case LIKE:
             return evaluateLike(v1, v2);
         }
         throw new IllegalArgumentException("Unknown operator: " + operator);
     }
 
+    private static CoreValue convert(CoreValueFactory vf, CoreValue v, int 
targetType) {
+        // TODO support full set of conversion features defined in the JCR spec
+        // at 3.6.4 Property Type Conversion
+        // re-use existing code if possible
+        int sourceType = v.getType();
+        if (sourceType == targetType) {
+            return v;
+        }
+        switch (sourceType) {
+        case PropertyType.STRING:
+            switch(targetType) {
+            case PropertyType.BINARY:
+                try {
+                    byte[] data = v.getString().getBytes("UTF-8");
+                    return vf.createValue(new ByteArrayInputStream(data));
+                } catch (IOException e) {
+                    // I don't know in what case that could really occur
+                    // except if UTF-8 isn't supported
+                    throw new IllegalArgumentException(v.getString(), e);
+                }
+            case PropertyType.DATE:
+
+            }
+        case PropertyType.BOOLEAN:
+            return vf.createValue(v.getBoolean());
+        case PropertyType.DATE:
+            return vf.createValue(v.getString(), PropertyType.DATE);
+        case PropertyType.LONG:
+            return vf.createValue(v.getLong());
+        case PropertyType.DOUBLE:
+            return vf.createValue(v.getDouble());
+        case PropertyType.DECIMAL:
+            return vf.createValue(v.getString(), PropertyType.DECIMAL);
+        case PropertyType.NAME:
+            return vf.createValue(v.getString(), PropertyType.NAME);
+        case PropertyType.PATH:
+            return vf.createValue(v.getString(), PropertyType.PATH);
+        case PropertyType.REFERENCE:
+            return vf.createValue(v.getString(), PropertyType.REFERENCE);
+        case PropertyType.WEAKREFERENCE:
+            return vf.createValue(v.getString(), PropertyType.WEAKREFERENCE);
+        case PropertyType.URI:
+            return vf.createValue(v.getString(), PropertyType.URI);
+        case PropertyType.BINARY:
+            try {
+                byte[] data = v.getString().getBytes("UTF-8");
+                return vf.createValue(new ByteArrayInputStream(data));
+            } catch (IOException e) {
+                // I don't know in what case that could really occur
+                // except if UTF-8 isn't supported
+                throw new IllegalArgumentException(v.getString(), e);
+            }
+        }
+        throw new IllegalArgumentException("Unknown property type: " + 
targetType);
+    }
+
     private static boolean evaluateLike(CoreValue v1, CoreValue v2) {
         LikePattern like = new LikePattern(v2.getString());
         return like.matches(v1.getString());

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/ConstraintImpl.java
 Tue May 15 08:48:03 2012
@@ -28,7 +28,9 @@ public abstract class ConstraintImpl ext
     public abstract boolean evaluate();
 
     /**
-     * Apply the condition to the filter, further restricting the filter if 
possible.
+     * Apply the condition to the filter, further restricting the filter if
+     * possible. This may also verify the data types are compatible, and that
+     * paths are valid.
      *
      * @param f the filter
      */

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/EquiJoinConditionImpl.java
 Tue May 15 08:48:03 2012
@@ -83,7 +83,6 @@ public class EquiJoinConditionImpl exten
         if (v1 == null) {
             return false;
         }
-        // TODO data type mapping
         CoreValue v2 = selector2.currentProperty(property2Name);
         return v2 != null && v1.equals(v2);
     }

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/FullTextSearchScoreImpl.java
 Tue May 15 08:48:03 2012
@@ -24,6 +24,7 @@ import org.apache.jackrabbit.oak.query.i
 public class FullTextSearchScoreImpl extends DynamicOperandImpl {
 
     private final String selectorName;
+    private SelectorImpl selector;
 
     public FullTextSearchScoreImpl(String selectorName) {
         this.selectorName = selectorName;
@@ -49,6 +50,13 @@ public class FullTextSearchScoreImpl ext
         return null;
     }
 
+    public void bindSelector(SourceImpl source) {
+        selector = source.getSelector(selectorName);
+        if (selector == null) {
+            throw new IllegalArgumentException("Unknown selector: " + 
selectorName);
+        }
+    }
+
     @Override
     public void apply(FilterImpl f, Operator operator, CoreValue v) {
         // TODO support fulltext index conditions (score)

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/JoinImpl.java
 Tue May 15 08:48:03 2012
@@ -70,30 +70,30 @@ public class JoinImpl extends SourceImpl
     }
 
     @Override
-    public void init(Query qom) {
+    public void init(Query query) {
         switch (joinType) {
         case INNER:
             left.setQueryConstraint(queryConstraint);
             right.setQueryConstraint(queryConstraint);
             right.setJoinCondition(joinCondition);
-            left.init(qom);
-            right.init(qom);
+            left.init(query);
+            right.init(query);
             break;
         case LEFT_OUTER:
             left.setQueryConstraint(queryConstraint);
             right.setOuterJoin(true);
             right.setQueryConstraint(queryConstraint);
             right.setJoinCondition(joinCondition);
-            left.init(qom);
-            right.init(qom);
+            left.init(query);
+            right.init(query);
             break;
         case RIGHT_OUTER:
             right.setQueryConstraint(queryConstraint);
             left.setOuterJoin(true);
             left.setQueryConstraint(queryConstraint);
             left.setJoinCondition(joinCondition);
-            right.init(qom);
-            left.init(qom);
+            right.init(query);
+            left.init(query);
             // TODO right outer join: verify whether converting
             // to left outer join is always correct (given the current 
restrictions)
             joinType = JoinType.LEFT_OUTER;
@@ -169,7 +169,7 @@ public class JoinImpl extends SourceImpl
 
     @Override
     public String currentPath() {
-        // TODO
+        // TODO join: what is the path of a join? it this method ever called?
         return left.currentPath();
     }
 

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/LengthImpl.java
 Tue May 15 08:48:03 2012
@@ -18,6 +18,7 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
+import javax.jcr.PropertyType;
 import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
@@ -49,15 +50,29 @@ public class LengthImpl extends DynamicO
         if (v == null) {
             return null;
         }
-        // TODO LENGTH(..) is the length of the string representation?
-        String value = v.getString();
-        return query.getValueFactory().createValue(value.length());
+        return query.getValueFactory().createValue(v.length());
     }
 
     @Override
     public void apply(FilterImpl f, Operator operator, CoreValue v) {
-        // ignore
-        // TODO LENGTH(x) conditions: can use IS NOT NULL?
+        switch (v.getType()) {
+        case PropertyType.LONG:
+        case PropertyType.DECIMAL:
+        case PropertyType.DOUBLE:
+            // ok - comparison with a number
+            break;
+        case PropertyType.BINARY:
+        case PropertyType.STRING:
+        case PropertyType.DATE:
+            // ok - compare with a string literal
+            break;
+        default:
+            throw new IllegalArgumentException(
+                    "Can not compare the length with a constant of type "
+                            + PropertyType.nameFromValue(v.getType()) +
+                            " and value " + v.toString());
+        }
+        // TODO LENGTH(x) conditions: can use IS NOT NULL as a condition?
     }
 
 }

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/PropertyValueImpl.java
 Tue May 15 08:48:03 2012
@@ -18,10 +18,9 @@
  */
 package org.apache.jackrabbit.oak.query.ast;
 
-import org.apache.jackrabbit.mk.json.JsopTokenizer;
 import org.apache.jackrabbit.mk.simple.NodeImpl;
-import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
 
 public class PropertyValueImpl extends DynamicOperandImpl {
@@ -76,11 +75,8 @@ public class PropertyValueImpl extends D
         if (!n.hasProperty(name)) {
             return null;
         }
-        // TODO data type mapping
         String value = n.getProperty(name);
-        value = JsopTokenizer.decodeQuoted(value);
-        return query.getValueFactory().createValue(value);
-
+        return getCoreValue(value);
     }
 
     public void bindSelector(SourceImpl source) {

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
 Tue May 15 08:48:03 2012
@@ -19,7 +19,6 @@
 package org.apache.jackrabbit.oak.query.ast;
 
 import org.apache.jackrabbit.mk.api.MicroKernel;
-import org.apache.jackrabbit.mk.json.JsopTokenizer;
 import org.apache.jackrabbit.mk.simple.NodeImpl;
 import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.query.Query;
@@ -32,6 +31,10 @@ public class SelectorImpl extends Source
     // TODO jcr:path isn't an official feature, support it?
     private static final String PATH = "jcr:path";
 
+    private static final String JCR_PRIMARY_TYPE = "jcr:primaryType";
+
+    private static final String TYPE_BASE = "nt:base";
+
     protected QueryIndex index;
 
     private final String nodeTypeName, selectorName;
@@ -79,6 +82,7 @@ public class SelectorImpl extends Source
 
     private FilterImpl createFilter() {
         FilterImpl f = new FilterImpl(this);
+        f.setNodeType(nodeTypeName);
         if (joinCondition != null) {
             joinCondition.apply(f);
         }
@@ -94,7 +98,28 @@ public class SelectorImpl extends Source
 
     @Override
     public boolean next() {
-        return cursor == null ? false : cursor.next();
+        if (cursor == null) {
+            return false;
+        }
+        while (true) {
+            boolean result = cursor.next();
+            if (!result) {
+                return false;
+            }
+            if (nodeTypeName.equals(TYPE_BASE)) {
+                return true;
+            }
+            NodeImpl n = cursor.currentNode();
+            String primaryType = n.getProperty(JCR_PRIMARY_TYPE);
+            if (primaryType == null) {
+                return true;
+            }
+            CoreValue v = getCoreValue(primaryType);
+            // TODO node type matching
+            if (nodeTypeName.equals(v.getString())) {
+                return true;
+            }
+        }
     }
 
     @Override
@@ -110,7 +135,15 @@ public class SelectorImpl extends Source
     public CoreValue currentProperty(String propertyName) {
         if (propertyName.equals(PATH)) {
             String p = currentPath();
-            return p == null ? null : query.getValueFactory().createValue(p);
+            if (p == null) {
+                return null;
+            }
+            String local = getLocalPath(p);
+            if (local == null) {
+                // not a local path
+                return null;
+            }
+            return query.getValueFactory().createValue(local);
         }
         NodeImpl n = currentNode();
         if (n == null) {
@@ -120,13 +153,11 @@ public class SelectorImpl extends Source
         if (value == null) {
             return null;
         }
-        // TODO data type mapping
-        value = JsopTokenizer.decodeQuoted(value);
-        return query.getValueFactory().createValue(value);
+        return getCoreValue(value);
     }
 
     @Override
-    public void init(Query qom) {
+    public void init(Query query) {
         // nothing to do
     }
 

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SourceImpl.java
 Tue May 15 08:48:03 2012
@@ -29,32 +29,90 @@ public abstract class SourceImpl extends
     protected boolean join;
     protected boolean outerJoin;
 
+    /**
+     * Set the complete constraint of the query (the WHERE ... condition).
+     *
+     * @param queryConstraint the constraint
+     */
     public void setQueryConstraint(ConstraintImpl queryConstraint) {
         this.queryConstraint = queryConstraint;
     }
 
+    /**
+     * Set the join condition (the ON ... condition).
+     *
+     * @param joinCondition the join condition
+     */
     public void setJoinCondition(JoinConditionImpl joinCondition) {
         this.joinCondition = joinCondition;
     }
 
+    /**
+     * Set whether this source is the right hand side of a left outer join.
+     *
+     * @param outerJoin true if yes
+     */
     public void setOuterJoin(boolean outerJoin) {
         this.outerJoin = outerJoin;
     }
 
-    public abstract void init(Query qom);
-
+    /**
+     * Initialize the query. This will 'wire' the selectors with the
+     * constraints.
+     *
+     * @param query the query
+     */
+    public abstract void init(Query query);
+
+    /**
+     * Get the selector with the given name, or null if not found.
+     *
+     * @param selectorName the selector name
+     * @return the selector, or null
+     */
     public abstract SelectorImpl getSelector(String selectorName);
 
+    /**
+     * Get the query plan.
+     *
+     * @return the query plan
+     */
     public abstract String getPlan();
 
+    /**
+     * Prepare executing the query. This method will decide which index to use.
+     *
+     * @param mk the MicroKernel
+     */
     public abstract void prepare(MicroKernel mk);
 
+    /**
+     * Execute the query. The current node is set to before the first row.
+     *
+     * @param revisionId the revision to use
+     */
     public abstract void execute(String revisionId);
 
+    /**
+     * Go to the next node for the given source. This will also filter the
+     * result for the right node type if required.
+     *
+     * @return true if there is a next row
+     */
     public abstract boolean next();
 
+    /**
+     * Get the current absolute path (including workspace name)
+     *
+     * @return the path
+     */
     public abstract String currentPath();
 
+    /**
+     * Get the current node.
+     *
+     * @return the node
+     */
     public abstract NodeImpl currentNode();
 
 }

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
 Tue May 15 08:48:03 2012
@@ -119,7 +119,7 @@ public class FilterImpl implements Filte
     public void setAlwaysFalse() {
         propertyRestrictions.clear();
         valuePrefix = "none";
-        nodeType = "none";
+        nodeType = "";
         path = "/";
         pathRestriction = PathRestriction.EXACT;
         alwaysFalse = true;

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/PropertyContentIndex.java
 Tue May 15 08:48:03 2012
@@ -121,6 +121,7 @@ public class PropertyContentIndex implem
         public boolean next() {
             if (it.hasNext()) {
                 currentPath = it.next();
+                currentNode = null;
                 return true;
             }
             return false;

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java
 Tue May 15 08:48:03 2012
@@ -16,22 +16,39 @@
  */
 package org.apache.jackrabbit.oak.query;
 
+import javax.jcr.GuestCredentials;
+import org.apache.jackrabbit.mk.api.MicroKernel;
 import org.apache.jackrabbit.mk.core.MicroKernelImpl;
 import org.apache.jackrabbit.mk.index.IndexWrapper;
+import org.apache.jackrabbit.mk.index.Indexer;
+import org.apache.jackrabbit.oak.api.ContentSession;
 import org.apache.jackrabbit.oak.api.CoreValueFactory;
-import org.apache.jackrabbit.oak.kernel.KernelNodeStore;
-import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.api.QueryEngine;
+import org.apache.jackrabbit.oak.core.ContentRepositoryImpl;
 
 /**
  * AbstractQueryTest...
  */
 public abstract class AbstractQueryTest {
 
-    // TODO improve: use ContentRepository here instead of creating mk 
instance.
-    protected final IndexWrapper mk = new IndexWrapper(new MicroKernelImpl());
-
-    protected final NodeStore store = new KernelNodeStore(mk);
-
-    protected final CoreValueFactory vf = store.getValueFactory();
+    protected final IndexWrapper mk;
+    protected final ContentRepositoryImpl rep;
+    protected final CoreValueFactory vf;
+    protected final QueryEngine qe;
+    protected final ContentSession session;
+
+    {
+        MicroKernel rawMk = new MicroKernelImpl();
+        mk = new IndexWrapper(rawMk);
+        Indexer indexer = new Indexer(mk, rawMk, Indexer.INDEX_CONFIG_ROOT);
+        rep = new ContentRepositoryImpl(mk, indexer);
+        try {
+            session = rep.login(new GuestCredentials(), "default");
+            vf = session.getCoreValueFactory();
+            qe = session.getQueryEngine();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
 
 }
\ No newline at end of file

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryTest.java
 Tue May 15 08:48:03 2012
@@ -16,7 +16,6 @@ package org.apache.jackrabbit.oak.query;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import java.io.FileOutputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.LineNumberReader;
@@ -28,15 +27,9 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.jackrabbit.oak.api.AuthInfo;
-import org.apache.jackrabbit.oak.api.ContentSession;
 import org.apache.jackrabbit.oak.api.CoreValue;
-import org.apache.jackrabbit.oak.api.CoreValueFactory;
-import org.apache.jackrabbit.oak.api.QueryEngine;
 import org.apache.jackrabbit.oak.api.Result;
 import org.apache.jackrabbit.oak.api.ResultRow;
-import org.apache.jackrabbit.oak.api.Root;
-import org.apache.jackrabbit.oak.spi.QueryIndexProvider;
 import org.junit.Test;
 
 /**
@@ -44,42 +37,6 @@ import org.junit.Test;
  */
 public class QueryTest extends AbstractQueryTest {
 
-    private QueryIndexProvider ip = mk.getIndexer();
-    private QueryEngineImpl qe = new QueryEngineImpl(store, mk, ip);
-    private ContentSession session = new ContentSession() {
-
-        @Override
-        public AuthInfo getAuthInfo() {
-            return null;
-        }
-
-        @Override
-        public CoreValueFactory getCoreValueFactory() {
-            return null;
-        }
-
-        @Override
-        public Root getCurrentRoot() {
-            return null;
-        }
-
-        @Override
-        public QueryEngine getQueryEngine() {
-            return null;
-        }
-
-        @Override
-        public String getWorkspaceName() {
-            return "/";
-        }
-
-        @Override
-        public void close() throws IOException {
-            // ignore
-        }
-
-    };
-
     @Test
     public void script() throws Exception {
         test("queryTest.txt");

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryTest.txt
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryTest.txt?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryTest.txt
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/queryTest.txt
 Tue May 15 08:48:03 2012
@@ -23,14 +23,14 @@
 
 # test the property content index
 
-commit / + "test": { "a": { "id": "10" }, "b": { "id" : "20" }}
+commit /default + "test": { "a": { "id": "10" }, "b": { "id" : "20" }}
 commit /jcr:system/indexes + "property:id": {}
 
 explain select * from [nt:base] where id = '10'
 nt:base AS nt:base /* propertyIndex "id [10..10]" */
 
 select * from [nt:base] where id = '10'
-/test/a
+/default/test/a
 
 select [jcr:path], * from [nt:base] where id = '10'
 /test/a, null
@@ -38,68 +38,64 @@ select [jcr:path], * from [nt:base] wher
 explain select * from [nt:base] where id > '10'
 nt:base AS nt:base /* traverse "//*" */
 
-commit / - "test"
+commit /default - "test"
 commit /jcr:system/indexes - "property:id"
 
 # other tests
 
-commit / + "test": { "jcr:resource": {}, "resource": { "x" : {}}}
+commit /default + "test": { "jcr:resource": {}, "resource": { "x" : {}}}
 
 select * from [nt:base] where id = -1
 
 explain select * from [nt:base] as b where ischildnode(b, '/test')
-nt:base AS b /* traverse "/test/*" */
+nt:base AS b /* traverse "/default/test/*" */
 
 explain select * from [nt:base] as b where isdescendantnode(b, '/test')
-nt:base AS b /* traverse "/test//*" */
+nt:base AS b /* traverse "/default/test//*" */
 
 select * from [nt:base] as b where ischildnode(b, '/test')
-/test/jcr:resource
-/test/resource
+/default/test/jcr:resource
+/default/test/resource
 
 select * from [nt:base] as b where issamenode(b, '/test')
-/test
+/default/test
 
 select * from [nt:base] where name() = 'resource'
-/test/resource
+/default/test/resource
 
 select * from [nt:base] as b where localname(b) = 'resource'
-/test/jcr:resource
-/test/resource
+/default/test/jcr:resource
+/default/test/resource
 
 select * from [nt:base] as x where isdescendantnode(x, '/')
-/
-/jcr:system
-/jcr:system/indexes
-/test
-/test/jcr:resource
-/test/resource
-/test/resource/x
+/default/test
+/default/test/jcr:resource
+/default/test/resource
+/default/test/resource/x
 
-commit / - "test"
+commit /default - "test"
 
-commit / + "parents": { "p0": {"id": "0"}, "p1": {"id": "1"}, "p2": {"id": 
"2"}}
-commit / + "children": { "c1": {"p": "1"}, "c2": {"p": "1"}, "c3": {"p": "2"}, 
"c4": {"p": "3"}}
+commit /default + "parents": { "p0": {"id": "0"}, "p1": {"id": "1"}, "p2": 
{"id": "2"}}
+commit /default + "children": { "c1": {"p": "1"}, "c2": {"p": "1"}, "c3": 
{"p": "2"}, "c4": {"p": "3"}}
 
 # relative property
 select * from [nt:base] where [c1/p] = '1'
-/children
+/default/children
 
 select * from [nt:base] as p where p.[jcr:path] = '/parents'
-/parents
+/default/parents
 
 select * from [nt:base] as p inner join [nt:base] as p2 on ischildnode(p2, p) 
where p.[jcr:path] = '/'
-/, /children
-/, /jcr:system
-/, /parents
+/default, /default/children
+/default, /default/parents
 
 select * from [nt:base] as p inner join [nt:base] as p2 on 
isdescendantnode(p2, p) where p.[jcr:path] = '/parents'
-/parents, /parents/p0
-/parents, /parents/p1
-/parents, /parents/p2
+/default/parents, /default/parents/p0
+/default/parents, /default/parents/p1
+/default/parents, /default/parents/p2
 
 select * from [nt:base] as p inner join [nt:base] as p2 on issamenode(p2, p) 
where p.[jcr:path] = '/parents'
-/parents, /parents
+/default/parents, /default/parents
 
 select id from [nt:base] where id is not null
 0
@@ -112,79 +108,82 @@ select id from [nt:base] where id is not
 0
 
 select * from [nt:base] as c right outer join [nt:base] as p on p.id = c.p 
where p.id is not null
-/children/c1, /parents/p1
-/children/c2, /parents/p1
-/children/c3, /parents/p2
-null, /parents/p0
+/default/children/c1, /default/parents/p1
+/default/children/c2, /default/parents/p1
+/default/children/c3, /default/parents/p2
+null, /default/parents/p0
 
 select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p 
where p.id is not null
-/parents/p0, null
-/parents/p1, /children/c1
-/parents/p1, /children/c2
-/parents/p2, /children/c3
+/default/parents/p0, null
+/default/parents/p1, /default/children/c1
+/default/parents/p1, /default/children/c2
+/default/parents/p2, /default/children/c3
 
 select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p 
where p.id is not null and c.p is null
-/parents/p0, null
+/default/parents/p0, null
 
 select * from [nt:base] as p left outer join [nt:base] as c on p.id = c.p 
where p.id is not null and c.p is not null
-/parents/p1, /children/c1
-/parents/p1, /children/c2
-/parents/p2, /children/c3
+/default/parents/p1, /default/children/c1
+/default/parents/p1, /default/children/c2
+/default/parents/p2, /default/children/c3
 
 select * from [nt:base] as p inner join [nt:base] as c on p.id = c.p
-/parents/p1, /children/c1
-/parents/p1, /children/c2
-/parents/p2, /children/c3
+/default/parents/p1, /default/children/c1
+/default/parents/p1, /default/children/c2
+/default/parents/p2, /default/children/c3
 
 explain select * from [nt:base] as p inner join [nt:base] as c on p.id = c.p
 nt:base AS p /* traverse "//*" */ INNER JOIN nt:base AS c /* traverse "//*" */
 
-commit / - "parents"
-commit / - "children"
+commit /default - "parents"
+commit /default - "children"
 
-commit / + "test": { "hello": { "x": "1" }, "world": { "x": "2" } }
-commit / + "test2": { "id":"1", "x": "2" }
+commit /default + "test": { "hello": { "x": "1" }, "world": { "x": "2" } }
+commit /default + "test2": { "id":"1", "x": "2" }
 
 select * from [nt:base]
 /
+/default
+/default/test
+/default/test/hello
+/default/test/world
+/default/test2
 /jcr:system
 /jcr:system/indexes
-/test
-/test/hello
-/test/world
-/test2
 
 select * from [nt:base] where id = '1'
-/test2
+/default/test2
 
 select * from [nt:base] where id = '1' and x = '2'
-/test2
+/default/test2
 
 select * from [nt:base] where id = '1' or x = '2'
-/test/world
-/test2
+/default/test/world
+/default/test2
 
 select * from [nt:base] where not (id = '1' or x = '2')
 /
+/default
+/default/test
+/default/test/hello
 /jcr:system
 /jcr:system/indexes
-/test
-/test/hello
 
 select * from [nt:base] where x is null
 /
+/default
+/default/test
 /jcr:system
 /jcr:system/indexes
-/test
 
-commit / - "test"
-commit / - "test2"
+commit /default - "test"
+commit /default - "test2"
 
-commit / + "test": { "name": "hello" }
-commit / + "test2": { "name": "World!" }
-commit / + "test3": { "name": "Hallo" }
-commit / + "test4": { "name": "10%" }
-commit / + "test5": { "name": "10 percent" }
+commit /default + "test": { "name": "hello" }
+commit /default + "test2": { "name": "World!" }
+commit /default + "test3": { "name": "Hallo" }
+commit /default + "test4": { "name": "10%" }
+commit /default + "test5": { "name": "10 percent" }
 
 select name from [nt:base] order by upper(name)
 10 percent
@@ -195,37 +194,38 @@ World!
 null
 null
 null
+null
 
 select * from [nt:base] where length(name) = 5
-/test
-/test3
+/default/test
+/default/test3
 
 select * from [nt:base] where upper(name) = 'HELLO'
-/test
+/default/test
 
 select * from [nt:base] where lower(name) = 'world!'
-/test2
+/default/test2
 
 select * from [nt:base] where name like 'W%'
-/test2
+/default/test2
 
 select * from [nt:base] where name like '%o_%'
-/test2
+/default/test2
 
 select * from [nt:base] where name like '__llo'
-/test
-/test3
+/default/test
+/default/test3
 
 select * from [nt:base] where upper(name) like 'H_LLO'
-/test
-/test3
+/default/test
+/default/test3
 
 select * from [nt:base] where upper(name) like 'H\_LLO'
 
 select * from [nt:base] where upper(name) like '10%'
-/test4
-/test5
+/default/test4
+/default/test5
 
 select * from [nt:base] where upper(name) like '10\%'
-/test4
+/default/test4
 

Modified: 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryResultImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryResultImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryResultImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryResultImpl.java
 Tue May 15 08:48:03 2012
@@ -32,6 +32,7 @@ import javax.jcr.NodeIterator;
 import javax.jcr.RepositoryException;
 import javax.jcr.query.QueryResult;
 import javax.jcr.query.RowIterator;
+import java.util.Arrays;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
@@ -61,7 +62,7 @@ public class QueryResultImpl implements 
     }
 
     @Override
-    public String[] getSelectorNames() throws RepositoryException {
+    public String[] getSelectorNames() {
         return result.getSelectorNames();
     }
 
@@ -80,10 +81,12 @@ public class QueryResultImpl implements 
                 current = null;
                 while(it.hasNext()) {
                     ResultRow r = it.next();
-                    String path = r.getPath();
-                    if (PathUtils.isAncestor(pathFilter, path)) {
-                        current = new RowImpl(r, valueFactory);
-                        break;
+                    for (String s : getSelectorNames()) {
+                        String path = r.getPath(s);
+                        if (PathUtils.isAncestor(pathFilter, path)) {
+                            current = new RowImpl(sessionDelegate, r, 
valueFactory);
+                            break;
+                        }
                     }
                 }
             }
@@ -114,6 +117,9 @@ public class QueryResultImpl implements 
 
     @Override
     public NodeIterator getNodes() throws RepositoryException {
+        if (getSelectorNames().length > 1) {
+            throw new RepositoryException("Query contains more than one 
selector: " + Arrays.toString(getSelectorNames()));
+        }
         Iterator<NodeImpl> it = new Iterator<NodeImpl>() {
 
             private final Iterator<? extends ResultRow> it = 
result.getRows().iterator();

Modified: 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/RowImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/RowImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/RowImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/RowImpl.java
 Tue May 15 08:48:03 2012
@@ -20,6 +20,9 @@ package org.apache.jackrabbit.oak.jcr.qu
 
 import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.api.ResultRow;
+import org.apache.jackrabbit.oak.jcr.NodeDelegate;
+import org.apache.jackrabbit.oak.jcr.NodeImpl;
+import org.apache.jackrabbit.oak.jcr.SessionDelegate;
 import org.apache.jackrabbit.oak.jcr.value.ValueFactoryImpl;
 
 import javax.jcr.Node;
@@ -32,34 +35,47 @@ import javax.jcr.query.Row;
  */
 public class RowImpl implements Row {
 
+    private final SessionDelegate sessionDelegate;
     private final ResultRow row;
     private final ValueFactoryImpl valueFactory;
 
-    public RowImpl(ResultRow row, ValueFactoryImpl valueFactory) {
+    public RowImpl(SessionDelegate sessionDelegate, ResultRow row, 
ValueFactoryImpl valueFactory) {
+        this.sessionDelegate = sessionDelegate;
         this.row = row;
         this.valueFactory = valueFactory;
     }
 
     @Override
     public Node getNode() throws RepositoryException {
-        // TODO row node
-        return null;
+        return getNodeForPath(getPath());
     }
 
     @Override
     public Node getNode(String selectorName) throws RepositoryException {
-        // TODO row node
-        return null;
+        return getNodeForPath(getPath(selectorName));
+    }
+
+    private Node getNodeForPath(String path) {
+        NodeDelegate d = sessionDelegate.getNode(path);
+        return new NodeImpl(d);
     }
 
     @Override
     public String getPath() throws RepositoryException {
-        return row.getPath();
+        try {
+            return row.getPath();
+        } catch (IllegalArgumentException e) {
+            throw new RepositoryException(e);
+        }
     }
 
     @Override
     public String getPath(String selectorName) throws RepositoryException {
-        return row.getPath(selectorName);
+        try {
+            return row.getPath(selectorName);
+        } catch (IllegalArgumentException e) {
+            throw new RepositoryException(e);
+        }
     }
 
     @Override
@@ -76,7 +92,11 @@ public class RowImpl implements Row {
 
     @Override
     public Value getValue(String columnName) throws RepositoryException {
-        return valueFactory.createValue(row.getValue(columnName));
+        try {
+            return valueFactory.createValue(row.getValue(columnName));
+        } catch (IllegalArgumentException e) {
+            throw new RepositoryException(e);
+        }
     }
 
     @Override

Modified: 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/qom/QueryObjectModelImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/qom/QueryObjectModelImpl.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/qom/QueryObjectModelImpl.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/qom/QueryObjectModelImpl.java
 Tue May 15 08:48:03 2012
@@ -64,7 +64,7 @@ public class QueryObjectModelImpl implem
 
     @Override
     public Column[] getColumns() {
-        return columns;
+        return columns == null ? new Column[0] : columns;
     }
 
     @Override
@@ -74,7 +74,7 @@ public class QueryObjectModelImpl implem
 
     @Override
     public Ordering[] getOrderings() {
-        return orderings;
+        return orderings == null ? new Ordering[0] : orderings;
     }
 
     @Override
@@ -155,7 +155,7 @@ public class QueryObjectModelImpl implem
             buff.append(" where ");
             buff.append(constraint);
         }
-        if (orderings != null) {
+        if (orderings != null && orderings.length > 0) {
             buff.append(" order by ");
             i = 0;
             for (Ordering o : orderings) {
@@ -170,18 +170,21 @@ public class QueryObjectModelImpl implem
 
     @Override
     public String getStoredQueryPath() throws RepositoryException {
-        // TODO Auto-generated method stub
+        // TODO not implemented yet
         return null;
     }
 
     @Override
-    public Node storeAsNode(String arg0) throws RepositoryException {
-        // TODO Auto-generated method stub
-        return null;
+    public Node storeAsNode(String absPath) throws RepositoryException {
+        return queryManager.createQuery(getStatement(), 
Query.JCR_SQL2).storeAsNode(absPath);
     }
 
     public void addBindVariable(BindVariableValueImpl var) {
         this.bindVariableMap.put(var.getBindVariableName(), null);
     }
 
+    public String toString() {
+        return getStatement();
+    }
+
 }

Modified: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java
 Tue May 15 08:48:03 2012
@@ -23,7 +23,6 @@ import static junit.framework.Assert.ass
 import static org.junit.Assert.assertFalse;
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
-import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.ValueFactory;
@@ -48,7 +47,6 @@ public class QueryTest extends AbstractR
 
     @Test
     public void simple() throws RepositoryException {
-        Repository repository = getRepository();
         Session session = createAnonymousSession();
         try {
             Node hello = session.getRootNode().addNode("hello");

Modified: 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/qom/QomTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/qom/QomTest.java?rev=1338601&r1=1338600&r2=1338601&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/qom/QomTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/qom/QomTest.java
 Tue May 15 08:48:03 2012
@@ -19,7 +19,6 @@
 package org.apache.jackrabbit.oak.jcr.query.qom;
 
 import static org.junit.Assert.assertEquals;
-import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.Value;


Reply via email to