You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2014/05/24 20:45:04 UTC

svn commit: r1597335 - in /jena/trunk/jena-arq/src: main/java/com/hp/hpl/jena/sparql/path/eval/ main/java/com/hp/hpl/jena/sparql/sse/builders/ main/java/com/hp/hpl/jena/sparql/util/graph/ test/java/com/hp/hpl/jena/sparql/path/

Author: andy
Date: Sat May 24 18:45:04 2014
New Revision: 1597335

URL: http://svn.apache.org/r1597335
Log:
JENA-631 - add rdfs:member calculation to property path evalution.

Added:
    jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TestPathPF.java   (with props)
Modified:
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/path/eval/PathEngine.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderPath.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/util/graph/GraphContainerUtils.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/util/graph/GraphList.java
    jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TS_Path.java

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/path/eval/PathEngine.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/path/eval/PathEngine.java?rev=1597335&r1=1597334&r2=1597335&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/path/eval/PathEngine.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/path/eval/PathEngine.java Sat May 24 18:45:04 2014
@@ -28,17 +28,19 @@ import org.apache.jena.atlas.iterator.Tr
 import com.hp.hpl.jena.graph.Graph ;
 import com.hp.hpl.jena.graph.Node ;
 import com.hp.hpl.jena.graph.Triple ;
-import com.hp.hpl.jena.sparql.core.Var ;
 import com.hp.hpl.jena.sparql.engine.binding.Binding ;
 import com.hp.hpl.jena.sparql.engine.binding.BindingFactory ;
 import com.hp.hpl.jena.sparql.path.P_NegPropSet ;
 import com.hp.hpl.jena.sparql.path.Path ;
 import com.hp.hpl.jena.sparql.path.eval.PathEvaluator.FilterExclude ;
 import com.hp.hpl.jena.sparql.util.Context ;
+import com.hp.hpl.jena.sparql.util.graph.GraphContainerUtils ;
+import com.hp.hpl.jena.sparql.util.graph.GraphList ;
+import com.hp.hpl.jena.sparql.vocabulary.ListPFunction ;
+import com.hp.hpl.jena.vocabulary.RDFS ;
 
 abstract public class PathEngine
 {
-
     private final Graph   graph ;
     private final Context context ;
 
@@ -69,7 +71,7 @@ abstract public class PathEngine
     // output) ;
 
     // --- Where we touch the graph
-    // Because it SP? or ?PO, no duplicates occur, so works for both strategies.
+    // Because for SP? or ?PO, no duplicates occur, so works for both strategies.
     protected final Iterator<Node> doOne(Node node, Node property) {
         Iterator<Node> iter2 = null ;
         if ( direction() ) {
@@ -167,25 +169,70 @@ abstract public class PathEngine
     }
 
     protected Iterator<Triple> graphFind(Node s, Node p, Node o) {
-        return graphFind(graph, s, p, o) ;
+        return graphFind(graph, s, p, o, context) ;
     }
 
     static Binding binding = BindingFactory.binding() ;
-
-    private/* package */static Iterator<Triple> graphFind(Graph graph, Node s, Node p, Node o) {
+    static Node RDFSmember = RDFS.Nodes.member ;
+    
+    
+    static Node ListMember = ListPFunction.member.asNode() ;
+    
+    
+    private/* package */static Iterator<Triple> graphFind(Graph graph, Node s, Node p, Node o, Context context) {
         // This is the only place this is called.
-        // It means we can add property functions here.s
+        // It means we can add property functions here.
+        if ( RDFSmember.equals(p) )
+            return GraphContainerUtils.rdfsMember(graph, s, o) ;
+        if ( ListMember.equals(p) )
+            return GraphList.listMember(graph, s, o) ;
         return graph.find(s, p, o) ;
     }
-
-    private static Node arg(Node x, String name) {
-        if ( x == null || Node.ANY.equals(x) ) { return Var.alloc(name) ; }
-        return x ;
-    }
-
-    private static Node value(Node x, Binding b) {
-        if ( !Var.isVar(x) )
-            return x ;
-        return b.get(Var.alloc(x)) ;
-    }
+    
+    // Not all property functions make sense in property path
+    // For example, ones taking list arguments only make sense at
+    // the start or finish, and then only in simple paths
+    // (e.g. ?x .../propertyFunction ?z) 
+    // which would have been packaged by the optimizer.
+    
+//        if ( p != null && p.isURI() ) {
+//            // XXX This is heavy weight
+//            PropertyFunctionRegistry reg = PropertyFunctionRegistry.chooseRegistry(context) ;
+//            PropertyFunctionFactory f = reg.get(p.getURI()) ;
+//            if ( f != null ) { 
+//                // Expensive.
+//                PropertyFunction pf = f.create(p.getURI()) ;
+//                // Must be a PFuncSimple -- no list arguments to the property function.
+//                if ( pf instanceof PFuncSimple) {
+//                    PFuncSimple pfs = (PFuncSimple)pf ;
+//                    Node sv = arg(s, "S") ;
+//                    Node ov = arg(o, "O") ;
+//                    QueryIterator qIter = pfs.execEvaluated(binding, sv, p, ov, new ExecutionContext(ARQ.getContext(), graph, null, null)) ;
+//                    if ( ! qIter.hasNext() )
+//                        return Iter.nullIterator() ;
+//                    List<Triple> array = new ArrayList<Triple>() ;
+//                    for ( ; qIter.hasNext() ; ) {
+//                        Binding b = qIter.next() ;
+//                        Node st = value(sv, b) ;
+//                        Node ot = value(ov, b) ;
+//                        array.add(Triple.create(st, p, ot)) ;
+//                    }
+//                    return array.iterator() ; 
+//                }
+//            }
+//        }
+//
+//        return graph.find(s, p, o) ;
+//    }
+//
+//    private static Node arg(Node x, String name) {
+//        if ( x == null || Node.ANY.equals(x) ) { return Var.alloc(name) ; }
+//        return x ;
+//    }
+//
+//    private static Node value(Node x, Binding b) {
+//        if ( !Var.isVar(x) )
+//            return x ;
+//        return b.get(Var.alloc(x)) ;
+//    }
 }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderPath.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderPath.java?rev=1597335&r1=1597334&r2=1597335&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderPath.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/sse/builders/BuilderPath.java Sat May 24 18:45:04 2014
@@ -76,7 +76,7 @@ public class BuilderPath
         
         dispatch.put(Tags.tagPathReverse,  buildReverse) ;
         dispatch.put(Tags.tagPathRev,      buildRev) ;
-        dispatch.put(Tags.tagPathLink,     buildTriple) ;   // Completeness.
+        dispatch.put(Tags.tagPathLink,     buildLink) ;   // Completeness.
         dispatch.put(Tags.tagPathNotOneOf, buildNotOneOf) ;
     }
     
@@ -315,7 +315,7 @@ public class BuilderPath
         }
     };
     
-    final protected Build buildTriple = new Build()
+    final protected Build buildLink = new Build()
     {
         @Override
         public Path make(ItemList list)

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/util/graph/GraphContainerUtils.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/util/graph/GraphContainerUtils.java?rev=1597335&r1=1597334&r2=1597335&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/util/graph/GraphContainerUtils.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/util/graph/GraphContainerUtils.java Sat May 24 18:45:04 2014
@@ -19,21 +19,22 @@
 package com.hp.hpl.jena.sparql.util.graph;
 
 import java.util.Collection ;
+import java.util.Iterator ;
 import java.util.SortedMap ;
 import java.util.TreeMap ;
 import java.util.regex.Matcher ;
 import java.util.regex.Pattern ;
 
+import org.apache.jena.atlas.logging.Log ;
+
 import com.hp.hpl.jena.graph.Graph ;
 import com.hp.hpl.jena.graph.Node ;
 import com.hp.hpl.jena.graph.Triple ;
 import com.hp.hpl.jena.sparql.expr.Expr ;
-
-import org.apache.jena.atlas.logging.Log ;
-
 import com.hp.hpl.jena.util.iterator.ExtendedIterator ;
+import com.hp.hpl.jena.util.iterator.Filter ;
 import com.hp.hpl.jena.vocabulary.RDF ;
-
+import com.hp.hpl.jena.vocabulary.RDFS ;
 
 public class GraphContainerUtils
 {
@@ -41,7 +42,8 @@ public class GraphContainerUtils
     private static final Node BAG = RDF.Bag.asNode() ;
     private static final Node ALT = RDF.Alt.asNode() ;
     private static final Node SEQ = RDF.Seq.asNode() ;
-    private static final String membershipPattern = RDF.getURI()+"_(\\d+)" ;
+    private static final String membershipPattern$ = RDF.getURI()+"_(\\d+)" ;
+    private static final Pattern membershipPattern = Pattern.compile(membershipPattern$) ;
     private static final int NOT_FOUND = -9999 ;
 
     public static Collection<Node> containerMembers(Graph graph, Node container)
@@ -95,7 +97,26 @@ public class GraphContainerUtils
     {
         return countContainerMember(graph, container, containerType, member, false) ;
     }
-
+    
+    private static Node RDFSmember = RDFS.member.asNode() ;
+    private static Filter<Triple> filterRDFSmember = new Filter<Triple>() {
+        @Override
+        public boolean accept(Triple triple) {
+            Node p = triple.getPredicate() ;
+            if ( ! triple.getPredicate().isURI() )
+                return false ;
+            if (RDFSmember.equals(p) )
+                return true ;
+            String u = triple.getPredicate().getURI() ;
+            return membershipPattern.matcher(u).matches() ;
+        } } ; 
+
+    /** Calculate graph.find(?, rdfs:member, ?) */ 
+    public static Iterator<Triple> rdfsMember(Graph graph, Node s, Node o) {
+        ExtendedIterator<Triple> iter = graph.find(s, Node.ANY, o) ;
+        return iter.filterKeep(filterRDFSmember)  ;
+    }
+    
     private static int countContainerMember(Graph graph, Node container, Node containerType, Node member, boolean stopEarly)
     {
         if ( graph == null )
@@ -126,9 +147,8 @@ public class GraphContainerUtils
                 Triple t = iter.next() ;
                 Node p = t.getPredicate() ;
                 String u = p.getURI() ;
-                
-                if ( u.matches(membershipPattern) )
-                {
+                 
+                if ( membershipPattern.matcher(u).matches() ) {
                     count ++ ;
                     if ( stopEarly )
                         return count ;
@@ -154,12 +174,11 @@ public class GraphContainerUtils
         return graph.contains(container, RDFtype, containerType) ; 
     }
     
-    static Pattern pattern = Pattern.compile(membershipPattern);
     private static int getIndex(Triple triple)
     {
         String u = triple.getPredicate().getURI() ;
         // Must be _nnn.
-        Matcher m = pattern.matcher(u);
+        Matcher m = membershipPattern.matcher(u);
         if ( ! m.find() )
             return NOT_FOUND ; 
         String index = m.group(1) ;

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/util/graph/GraphList.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/util/graph/GraphList.java?rev=1597335&r1=1597334&r2=1597335&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/util/graph/GraphList.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/util/graph/GraphList.java Sat May 24 18:45:04 2014
@@ -117,6 +117,27 @@ public class GraphList
 
     // ---------------------------------------------
     
+    /** Calculate ?s list:member ?o as if it were a graph.find */
+    public static Iterator<Triple> listMember(Graph graph, Node s, Node o) {
+        if ( isAny(s) ) {
+            if ( isAny(o)) {
+                
+            } else {
+                
+            }
+        }
+        
+        
+        //Set<Node> x = GraphList.findAllLists(graph) ;
+        
+        
+        return null ;
+    }
+
+    private static boolean isAny(Node x) {
+        return x == null || Node.ANY.equals(x) ; 
+    }
+    
     public static List<Node> members(GNode gnode)
     {
         List<Node> x = new ArrayList<Node>() ;

Modified: jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TS_Path.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TS_Path.java?rev=1597335&r1=1597334&r2=1597335&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TS_Path.java (original)
+++ jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TS_Path.java Sat May 24 18:45:04 2014
@@ -26,6 +26,7 @@ import org.junit.runners.Suite ;
 @Suite.SuiteClasses( {
     TestPath.class
     , TestPath2.class
+    , TestPathPF.class
 })
 
 public class TS_Path

Added: jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TestPathPF.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TestPathPF.java?rev=1597335&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TestPathPF.java (added)
+++ jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TestPathPF.java Sat May 24 18:45:04 2014
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 com.hp.hpl.jena.sparql.path;
+
+import java.util.ArrayList ;
+import java.util.Arrays ;
+import java.util.Iterator ;
+import java.util.List ;
+
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.junit.AfterClass ;
+import org.junit.BeforeClass ;
+import org.junit.Test ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.NodeFactory ;
+import com.hp.hpl.jena.query.ARQ ;
+import com.hp.hpl.jena.rdf.model.Bag ;
+import com.hp.hpl.jena.rdf.model.Model ;
+import com.hp.hpl.jena.rdf.model.ModelFactory ;
+import com.hp.hpl.jena.rdf.model.Seq ;
+import com.hp.hpl.jena.sparql.graph.GraphFactory ;
+import com.hp.hpl.jena.sparql.path.eval.PathEval ;
+import com.hp.hpl.jena.sparql.sse.SSE ;
+
+/** Tests of property functions in paths.
+ * A property function can get invoked in the regular way
+ * (propfunc) by simple property path flattening in the optimizer
+ * or by use in complex path expressions.
+ */  
+public class TestPathPF extends BaseTest
+{
+    static Graph graph = GraphFactory.createDefaultGraph() ;
+    static Node elt1 = SSE.parseNode("'elt1'") ;
+    static Node elt2 = SSE.parseNode("'elt2'") ;
+    static String base = "http://example/" ;
+    static Node node0 = NodeFactory.createURI(base+"node0") ;
+    static Node node1 = NodeFactory.createURI(base+"node1") ;
+    static Node node2 = NodeFactory.createURI(base+"node2") ;
+    
+    @BeforeClass public static void beforeClass() {
+        Model m = ModelFactory.createModelForGraph(graph) ;
+        Bag bag0 = m.createBag(base+"node0") ;
+        Bag bag1 = m.createBag(base+"node1") ;
+        Seq seq2 = m.createSeq(base+"node2") ;
+        bag1.add("elt1") ;
+        seq2.add("elt1") ;
+        seq2.add("elt2") ;
+    }
+    
+    @AfterClass public static void afterClass() {
+        graph = null ;
+    }
+    
+    @Test public void path_pf_00() {
+        Path path = SSE.parsePath("(link rdfs:member)") ;
+        eval(graph, node0, path) ;
+    }
+
+    @Test public void path_pf_01() {
+        Path path = SSE.parsePath("(path+ rdfs:member)") ;
+        eval(graph, Node.ANY, path, elt1,elt2) ;
+    }
+
+    @Test public void path_pf_02() {
+        Path path = SSE.parsePath("(link rdfs:member)") ;
+        evalReverse(graph, elt1, path, node1, node2) ;
+    }
+    
+    private static void evalReverse(Graph graph, Node start, Path path, Node... expected) {
+        Iterator<Node> iter = PathEval.evalReverse(graph, start, path, null) ;
+        check(iter, expected) ; 
+    }
+    
+    private static void eval(Graph graph, Node start, Path path, Node... expected) {
+        Iterator<Node> iter = PathEval.eval(graph, start, path, ARQ.getContext()) ;
+        check(iter, expected) ; 
+    }
+    
+    private static void check(Iterator<Node> iter, Node... expected) {
+        List<Node> x = Iter.toList(iter) ;
+//        assertEquals(expected.length, x.size()) ;
+        List<Node> r = Arrays.asList(expected) ;
+        if ( !sameUnorder(r,x) )
+            fail("Expected: "+r+" : Actual: "+x) ;
+    }
+    
+    private static <T> boolean sameUnorder(List<T> list1, List<T> list2) {
+        list2 = new ArrayList<T>(list2) ;
+        if ( list1.size() != list2.size() )
+            return false;
+        for ( T elt : list1 )
+            list2.remove(elt) ;
+        return list2.size() == 0 ;
+    }
+}

Propchange: jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TestPathPF.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain