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 22:08:06 UTC

svn commit: r1597342 - in /jena/trunk/jena-arq/src: main/java/com/hp/hpl/jena/sparql/path/eval/ main/java/com/hp/hpl/jena/sparql/pfunction/ main/java/com/hp/hpl/jena/sparql/util/graph/ main/java/com/hp/hpl/jena/sparql/vocabulary/ main/java/org/apache/j...

Author: andy
Date: Sat May 24 20:08:06 2014
New Revision: 1597342

URL: http://svn.apache.org/r1597342
Log:
JENA-631 - add list:member calculation to property path evaluation.

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/pfunction/PropertyFunctionRegistry.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/util/graph/GraphList.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/vocabulary/ListPFunction.java
    jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/other/GLib.java
    jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TestPathPF.java
    jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/util/TestList.java
    jena/trunk/jena-arq/src/test/java/org/apache/jena/atlas/junit/BaseTest.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=1597342&r1=1597341&r2=1597342&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 20:08:06 2014
@@ -33,6 +33,7 @@ import com.hp.hpl.jena.sparql.engine.bin
 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.pfunction.PropertyFunctionRegistry ;
 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 ;
@@ -43,8 +44,10 @@ abstract public class PathEngine
 {
     private final Graph   graph ;
     private final Context context ;
+    private final PropertyFunctionRegistry registry ; 
 
     protected PathEngine(Graph graph, Context context) {
+        this.registry = PropertyFunctionRegistry.chooseRegistry(context) ;
         this.graph = graph ;
         this.context = context ;
     }
@@ -172,12 +175,9 @@ abstract public class PathEngine
         return graphFind(graph, s, p, o, context) ;
     }
 
-    static Binding binding = BindingFactory.binding() ;
-    static Node RDFSmember = RDFS.Nodes.member ;
-    
-    
-    static Node ListMember = ListPFunction.member.asNode() ;
-    
+    private static Binding binding = BindingFactory.binding() ;
+    private static Node RDFSmember = RDFS.Nodes.member ;
+    private static Node ListMember = ListPFunction.nListMember ;
     
     private/* package */static Iterator<Triple> graphFind(Graph graph, Node s, Node p, Node o, Context context) {
         // This is the only place this is called.

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/pfunction/PropertyFunctionRegistry.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/pfunction/PropertyFunctionRegistry.java?rev=1597342&r1=1597341&r2=1597342&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/pfunction/PropertyFunctionRegistry.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/pfunction/PropertyFunctionRegistry.java Sat May 24 20:08:06 2014
@@ -144,12 +144,14 @@ public class PropertyFunctionRegistry
     /** Iterate over URIs */
     public Iterator<String> keys() { return registry.keySet().iterator() ; }
     
+    @SuppressWarnings("deprecation")
     private void loadStdDefs()
     {
         put(ListPFunction.member.getURI() , com.hp.hpl.jena.sparql.pfunction.library.listMember.class) ;
         put(ListPFunction.index.getURI() , com.hp.hpl.jena.sparql.pfunction.library.listIndex.class) ;
         put(ListPFunction.length.getURI() , com.hp.hpl.jena.sparql.pfunction.library.listLength.class) ;
 
+        // (Very) old forms
         put(ListPFunction.listMember.getURI() , com.hp.hpl.jena.sparql.pfunction.library.listMember.class) ;
         put(ListPFunction.listIndex.getURI() , com.hp.hpl.jena.sparql.pfunction.library.listIndex.class) ;
         put(ListPFunction.listLength.getURI() , com.hp.hpl.jena.sparql.pfunction.library.listLength.class) ;

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=1597342&r1=1597341&r2=1597342&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 20:08:06 2014
@@ -30,7 +30,11 @@ import com.hp.hpl.jena.graph.Node ;
 import com.hp.hpl.jena.graph.NodeFactory ;
 import com.hp.hpl.jena.graph.Triple ;
 import com.hp.hpl.jena.sparql.core.BasicPattern ;
+import com.hp.hpl.jena.sparql.vocabulary.ListPFunction ;
 
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.iterator.IteratorConcat ;
+import org.apache.jena.atlas.iterator.Transform ;
 import org.apache.jena.atlas.logging.Log ;
 
 import com.hp.hpl.jena.util.iterator.NiceIterator ;
@@ -118,20 +122,32 @@ 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) {
+    public static Iterator<Triple> listMember(Graph graph, final Node s, Node o) {
         if ( isAny(s) ) {
-            if ( isAny(o)) {
-                
-            } else {
-                
+            Set<Node> x = findAllLists(graph) ;
+            IteratorConcat<Triple> iterConcat = new IteratorConcat<Triple>() ;
+            for ( Node s2 : x ) {
+                Iterator<Triple> iter = listMember(graph, s2, o) ;
+                if ( iter.hasNext() )
+                    iterConcat.add(iter); 
             }
+            return iterConcat ;
         }
-        
-        
-        //Set<Node> x = GraphList.findAllLists(graph) ;
-        
-        
-        return null ;
+        GNode gn = new GNode(graph, s) ;
+        if ( ! isAny(o) ) {
+            if ( contains(gn, o) )
+                return Iter.singleton(Triple.create(s, ListPFunction.nListMember, o)) ;
+            else
+                return Iter.nullIterator() ;
+        }
+        List<Node> x = members(gn) ;
+        Transform<Node, Triple> transform = new Transform<Node, Triple>() {
+            @Override
+            public Triple convert(Node obj) {
+                return Triple.create(s, ListPFunction.nListMember, obj) ;
+            }
+        } ;
+        return Iter.map(x.iterator(), transform) ;
     }
 
     private static boolean isAny(Node x) {

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/vocabulary/ListPFunction.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/vocabulary/ListPFunction.java?rev=1597342&r1=1597341&r2=1597342&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/vocabulary/ListPFunction.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/vocabulary/ListPFunction.java Sat May 24 20:08:06 2014
@@ -18,6 +18,7 @@
 
 package com.hp.hpl.jena.sparql.vocabulary ;
 
+import com.hp.hpl.jena.graph.Node ;
 import com.hp.hpl.jena.rdf.model.Model ;
 import com.hp.hpl.jena.rdf.model.ModelFactory ;
 import com.hp.hpl.jena.rdf.model.Property ;
@@ -41,19 +42,34 @@ public class ListPFunction {
     /** <p>The namespace of the vocabulary as a resource</p> */
     public static final Resource NAMESPACE = m_model.createResource( NS );
     
+    /** @deprecated : list:length preferred */
+    @Deprecated
     public static final Property listLength = m_model.createProperty( "http://jena.hpl.hp.com/ARQ/list#listLength" );
     
     /** <p>Length relationship of a list [subject] to a length [object]</p> */
     public static final Property length = m_model.createProperty( "http://jena.hpl.hp.com/ARQ/list#length" );
     
+    /** @deprecated : list:index preferred */
+    @Deprecated
     public static final Property listIndex = m_model.createProperty( "http://jena.hpl.hp.com/ARQ/list#listIndex" );
     
     /** <p>Index relationship of a list [subject] to a query list (index member)</p> */
     public static final Property index = m_model.createProperty( "http://jena.hpl.hp.com/ARQ/list#index" );
     
+    /** @deprecated : list:member preferred */
+    @Deprecated
     public static final Property listMember = m_model.createProperty( "http://jena.hpl.hp.com/ARQ/list#listMember" );
     
     /** <p>Membership relationship of a list [subject] to a member [object] c.f. rdfs:member</p> */
     public static final Property member = m_model.createProperty( "http://jena.hpl.hp.com/ARQ/list#member" );
+
+    /** list:member as a node */
+    public static final Node nListMember = member.asNode() ;
+    
+    /** list:length as a node */
+    public static final Node nListLength = length.asNode() ;
+    
+    /** list:index as a node */
+    public static final Node nListIndex = member.asNode() ;
     
 }

Modified: jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/other/GLib.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/other/GLib.java?rev=1597342&r1=1597341&r2=1597342&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/other/GLib.java (original)
+++ jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/other/GLib.java Sat May 24 20:08:06 2014
@@ -43,21 +43,21 @@ public class GLib
     public static Iterator<Node> listSubjects(Graph graph)
     {
         ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, Node.ANY) ;
-        return Iter.iter(iter).map(projectTripeSubject).distinct() ;
+        return Iter.iter(iter).map(projectTripleSubject).distinct() ;
     }
 
     /** List the predicates in a graph (no duplicates) */
     public static Iterator<Node> listPredicates(Graph graph)
     {
         ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, Node.ANY) ;
-        return Iter.iter(iter).map(projectTripePredicate).distinct() ;
+        return Iter.iter(iter).map(projectTriplePredicate).distinct() ;
     }
     
     /** List the objects in a graph (no duplicates) */
     public static Iterator<Node> listObjects(Graph graph)
     {
         ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, Node.ANY) ;
-        return Iter.iter(iter).map(projectTripeObject).distinct() ;
+        return Iter.iter(iter).map(projectTripleObject).distinct() ;
     }
     
     private static Transform<Quad, Triple> transformQuad2Triple = new Transform<Quad, Triple> () {
@@ -89,15 +89,15 @@ public class GLib
     
     /** Project triple to subject */ 
     public static Iterator<Node> triple2subject(Iterator<Triple> iter)
-    { return Iter.map(iter, projectTripeSubject) ; }
+    { return Iter.map(iter, projectTripleSubject) ; }
     
     /** Project triple to predicate */ 
     public static Iterator<Node> triple2predicate(Iterator<Triple> iter)
-    { return Iter.map(iter, projectTripePredicate) ; }
+    { return Iter.map(iter, projectTriplePredicate) ; }
     
     /** Project triple to object */ 
     public static Iterator<Node> triple2object(Iterator<Triple> iter)
-    { return Iter.map(iter, projectTripeObject) ; }
+    { return Iter.map(iter, projectTripleObject) ; }
 
     /** Transform quad to graphname */
     public static Transform<Quad, Node> projectQuadGraphName = new Transform<Quad, Node>() {
@@ -116,15 +116,15 @@ public class GLib
         @Override public Node convert(Quad quad) { return quad.getObject() ; }
     } ;
     /** Transform triple to subject */ 
-    public static Transform<Triple, Node> projectTripeSubject   = new Transform<Triple, Node>() {
+    public static Transform<Triple, Node> projectTripleSubject   = new Transform<Triple, Node>() {
         @Override public Node convert(Triple triple) { return triple.getSubject() ; }
     } ;
     /** Transform triple to predicate */ 
-    public static Transform<Triple, Node> projectTripePredicate = new Transform<Triple, Node>() {
+    public static Transform<Triple, Node> projectTriplePredicate = new Transform<Triple, Node>() {
         @Override public Node convert(Triple triple) { return triple.getPredicate() ; }
     } ;
     /** Transform triple to object */ 
-    public static Transform<Triple, Node> projectTripeObject    = new Transform<Triple, Node>() {
+    public static Transform<Triple, Node> projectTripleObject    = new Transform<Triple, Node>() {
         @Override public Node convert(Triple triple) { return triple.getObject() ; }
     } ;
 }

Modified: 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=1597342&r1=1597341&r2=1597342&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TestPathPF.java (original)
+++ jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/path/TestPathPF.java Sat May 24 20:08:06 2014
@@ -18,17 +18,20 @@
 
 package com.hp.hpl.jena.sparql.path;
 
-import java.util.ArrayList ;
+import java.io.StringReader ;
 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.apache.jena.riot.Lang ;
+import org.apache.jena.riot.RDFDataMgr ;
 import org.junit.AfterClass ;
 import org.junit.BeforeClass ;
 import org.junit.Test ;
 
+import com.hp.hpl.jena.graph.Factory ;
 import com.hp.hpl.jena.graph.Graph ;
 import com.hp.hpl.jena.graph.Node ;
 import com.hp.hpl.jena.graph.NodeFactory ;
@@ -38,6 +41,7 @@ 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.graph.NodeConst ;
 import com.hp.hpl.jena.sparql.path.eval.PathEval ;
 import com.hp.hpl.jena.sparql.sse.SSE ;
 
@@ -48,16 +52,30 @@ import com.hp.hpl.jena.sparql.sse.SSE ;
  */  
 public class TestPathPF extends BaseTest
 {
-    static Graph graph = GraphFactory.createDefaultGraph() ;
+    static Graph graph1 = 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") ;
+
+    static Node s1 = NodeFactory.createURI("http://example/s1") ;
+    static Node s2 = NodeFactory.createURI("http://example/s2") ;
+    static Node s3 = NodeFactory.createURI("http://example/s3") ;
+    
+    private static String data = 
+        "prefix : <http://example/>\n" +
+        ":s1 :p (1 2 3) .\n"+
+        ":s2 :p () .\n" + 
+        ":s1 :p (4 5) .\n" +
+        ":s3 :p (8 9) .\n" ;
+    
+    private static Graph graph2 = Factory.createDefaultGraph() ;
+    static { RDFDataMgr.read(graph2, new StringReader(data), null, Lang.TTL); }
     
     @BeforeClass public static void beforeClass() {
-        Model m = ModelFactory.createModelForGraph(graph) ;
+        Model m = ModelFactory.createModelForGraph(graph1) ;
         Bag bag0 = m.createBag(base+"node0") ;
         Bag bag1 = m.createBag(base+"node1") ;
         Seq seq2 = m.createSeq(base+"node2") ;
@@ -67,24 +85,63 @@ public class TestPathPF extends BaseTest
     }
     
     @AfterClass public static void afterClass() {
-        graph = null ;
+        graph1 = null ;
     }
     
     @Test public void path_pf_00() {
         Path path = SSE.parsePath("(link rdfs:member)") ;
-        eval(graph, node0, path) ;
+        eval(graph1, node0, path, new Node[] {}) ;
     }
 
     @Test public void path_pf_01() {
         Path path = SSE.parsePath("(path+ rdfs:member)") ;
-        eval(graph, Node.ANY, path, elt1,elt2) ;
+        eval(graph1, Node.ANY, path, elt1,elt2) ;
     }
 
     @Test public void path_pf_02() {
         Path path = SSE.parsePath("(link rdfs:member)") ;
-        evalReverse(graph, elt1, path, node1, node2) ;
+        evalReverse(graph1, elt1, path, node1, node2) ;
+    }
+    
+    @Test public void path_pf_03() {
+        Path path = SSE.parsePath("(link rdfs:member)") ;
+        evalReverse(graph1, Node.ANY, path, node2, node2, node1) ;
     }
     
+
+    @Test public void path_pf_10() {
+        Path path = SSE.parsePath("(prefix ((list: <http://jena.hpl.hp.com/ARQ/list#>)) (seq :p (link list:member)))") ;
+        eval(graph2, s1, path, "1", "2", "3", "4", "5") ;
+    }
+    
+    @Test public void path_pf_11() {
+        Path path = SSE.parsePath("(prefix ((list: <http://jena.hpl.hp.com/ARQ/list#>)) (seq :p (link list:member)))") ;
+        eval(graph2, s2, path, new Node[] {}) ;
+    }
+
+    @Test public void path_pf_12() {
+        Path path = SSE.parsePath("(prefix ((list: <http://jena.hpl.hp.com/ARQ/list#>)) (seq :p (link list:member)))") ;
+        eval(graph2, s3, path, "8", "9") ;
+    }
+
+    @Test public void path_pf_13() {
+        Path path = SSE.parsePath("(prefix ((list: <http://jena.hpl.hp.com/ARQ/list#>)) (seq :p (link list:member)))") ;
+        evalReverse(graph2, NodeConst.nodeOne, path, s1) ;
+    }
+
+    @Test public void path_pf_14() {
+        Path path = SSE.parsePath("(prefix ((list: <http://jena.hpl.hp.com/ARQ/list#>)) (seq :p (link list:member)))") ;
+        evalReverse(graph2, NodeConst.nodeNil, path) ;
+    }
+
+    private static void eval(Graph graph, Node start, Path path, String... expected) {
+        Node[] r = new Node[expected.length] ;
+        for ( int i = 0 ; i < expected.length ; i++ ) {
+            r[i] = SSE.parseNode(expected[i]) ;
+        }
+        eval(graph, start, path, r) ;
+    }
+
     private static void evalReverse(Graph graph, Node start, Path path, Node... expected) {
         Iterator<Node> iter = PathEval.evalReverse(graph, start, path, null) ;
         check(iter, expected) ; 
@@ -96,19 +153,11 @@ public class TestPathPF extends BaseTest
     }
     
     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) ;
+        check(iter, Arrays.asList(expected)) ;
     }
-    
-    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 ;
+
+    private static void check(Iterator<Node> iter, List<Node> expected) {
+        List<Node> x = Iter.toList(iter) ;
+        assertEqualsUnordered(expected,x) ;
     }
 }

Modified: jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/util/TestList.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/util/TestList.java?rev=1597342&r1=1597341&r2=1597342&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/util/TestList.java (original)
+++ jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/util/TestList.java Sat May 24 20:08:06 2014
@@ -19,15 +19,22 @@
 package com.hp.hpl.jena.sparql.util;
 
 import java.io.StringReader ;
+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.apache.jena.riot.Lang ;
+import org.apache.jena.riot.RDFDataMgr ;
+import org.apache.jena.riot.other.GLib ;
 import org.junit.Test ;
 
 import com.hp.hpl.jena.datatypes.xsd.XSDDatatype ;
 import com.hp.hpl.jena.graph.* ;
 import com.hp.hpl.jena.rdf.model.Model ;
 import com.hp.hpl.jena.rdf.model.ModelFactory ;
+import com.hp.hpl.jena.sparql.sse.SSE ;
 import com.hp.hpl.jena.sparql.util.graph.GNode ;
 import com.hp.hpl.jena.sparql.util.graph.GraphList ;
 import com.hp.hpl.jena.vocabulary.RDF ;
@@ -198,4 +205,48 @@ public class TestList extends BaseTest
     private static String listStr_1 = preamble + "() ." ;
     private static String listStr_2 = preamble + "(1 2 3 4) ." ;
     private static String listStr_3 = preamble + "(1 2 1 2) ." ;
+    
+    private static String data = 
+        "prefix : <http://example/>\n" +
+        ":s1 :p (1 2 3) .\n"+
+        ":s2 :p () .\n" + 
+        ":s3 :p (8) .\n" ;
+    private static Node s1 = NodeFactory.createURI("http://example/s1") ;
+    private static Node s2 = NodeFactory.createURI("http://example/s2") ;
+    private static Node s3 = NodeFactory.createURI("http://example/s3") ;
+    
+    private static Graph graph = Factory.createDefaultGraph() ;
+    static { RDFDataMgr.read(graph, new StringReader(data), null, Lang.TTL); }
+    
+    
+    
+    @Test public void testGraphListMember_01() {
+        testGraphListMember(s1, node1, node2, node3) ;
+    }
+    
+    @Test public void testGraphListMember_02() {
+        testGraphListMember(s2) ;
+    }
+
+    @Test public void testGraphListMember_03() {
+        testGraphListMember(s3, SSE.parseNode("8")) ;
+    }
+
+    private static void testGraphListMember(Node s, Node...expected) {
+        Node list = listOf(graph, s) ;
+        Iterator<Triple> iter = GraphList.listMember(graph, list, Node.ANY) ;
+        Iterator<Node> x = GLib.triple2object(iter) ;
+        List<Node> z = Iter.toList(x) ;
+        check(z, expected) ;
+    }
+
+    private static Node listOf(Graph graph, Node node) {
+        return graph.find(node, p, Node.ANY).next().getObject() ;
+    }
+    
+    private static void check(List<Node> z, Node...expected) {
+        List<Node> x = Arrays.asList(expected) ;
+        assertEqualsUnordered(x, z);
+    }
+    
 }

Modified: jena/trunk/jena-arq/src/test/java/org/apache/jena/atlas/junit/BaseTest.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/org/apache/jena/atlas/junit/BaseTest.java?rev=1597342&r1=1597341&r2=1597342&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/test/java/org/apache/jena/atlas/junit/BaseTest.java (original)
+++ jena/trunk/jena-arq/src/test/java/org/apache/jena/atlas/junit/BaseTest.java Sat May 24 20:08:06 2014
@@ -18,9 +18,7 @@
 
 package org.apache.jena.atlas.junit;
 
-import java.util.ArrayDeque ;
-import java.util.Deque ;
-import java.util.Locale ;
+import java.util.* ;
 
 import org.apache.jena.atlas.logging.Log ;
 import org.apache.jena.riot.system.ErrorHandler ;
@@ -69,5 +67,14 @@ public class BaseTest extends Assert
         b = b.toLowerCase(Locale.ROOT) ;
         assertEquals(msg, a, b) ;
     }
-
+    
+    public static <T> void assertEqualsUnordered(List<T> list1, List<T> list2) {
+        if ( list1.size() != list2.size() )
+            fail("Expected: "+list1+" : Actual: "+list2) ;
+        List<T> list2a = new ArrayList<T>(list2) ;
+        for ( T elt : list1 )
+            list2a.remove(elt) ;
+        if ( list2a.size() != 0 )
+            fail("Expected: "+list1+" : Actual: "+list2) ;
+    }
 }