Author: andy
Date: Sat Jul 19 18:02:34 2014
New Revision: 1611937

URL: http://svn.apache.org/r1611937
Log:
JENA-745: Fixes for writing TriG (shared bnodes across graphs)

Added:
    jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-25.trig
    jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-26.trig
    jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-27.trig
    jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-28.trig
    jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-29.trig
    jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-30.trig
Modified:
    jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
    
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/writer/TriGWriter.java
    
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java
    
jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRiotWriterDataset.java

Modified: 
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java?rev=1611937&r1=1611936&r2=1611937&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java 
(original)
+++ jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java 
Sat Jul 19 18:02:34 2014
@@ -28,10 +28,7 @@ import static org.apache.jena.riot.write
 
 import java.io.OutputStream ;
 import java.io.Writer ;
-import java.util.ArrayList ;
-import java.util.Collection ;
-import java.util.List ;
-import java.util.Map ;
+import java.util.* ;
 
 import org.apache.jena.atlas.io.IndentedWriter ;
 import org.apache.jena.atlas.iterator.Iter ;
@@ -55,6 +52,7 @@ import com.hp.hpl.jena.rdf.model.AnonId 
 import com.hp.hpl.jena.sparql.ARQConstants ;
 import com.hp.hpl.jena.sparql.core.DatasetGraph ;
 import com.hp.hpl.jena.sparql.core.DatasetGraphFactory ;
+import com.hp.hpl.jena.sparql.core.Quad ;
 import com.hp.hpl.jena.sparql.util.Context ;
 import com.hp.hpl.jena.util.iterator.ExtendedIterator ;
 
@@ -130,6 +128,14 @@ public class RiotLib
         return profile(baseIRI, true, true, handler) ;
     }
 
+    /** Create a parser profile for the given setup
+     * @param baseIRI       Base IRI
+     * @param resolveIRIs   Whether to resolve IRIs
+     * @param checking      Whether to check 
+     * @param handler       Error handler
+     * @return ParserProfile
+     * @see #profile for per-language setup
+     */
     public static ParserProfile profile(String baseIRI, boolean resolveIRIs, 
boolean checking, ErrorHandler handler)
     {
         LabelToNode labelToNode = true
@@ -148,55 +154,72 @@ public class RiotLib
             return new ParserProfileBase(prologue, handler, labelToNode) ;
     }
 
-    public static Collection<Triple> triplesOfSubject(Graph graph, Node subj)
-    {
+    /** Get triples with the same subject */
+    public static Collection<Triple> triplesOfSubject(Graph graph, Node subj) {
         return triples(graph, subj, Node.ANY, Node.ANY) ;
     }
 
-    /* Get all the triples for the graph.find */
-    public static List<Triple> triples(Graph graph, Node s, Node p, Node o)
-    {
-        List<Triple> acc =  new ArrayList<>() ;
+    /** Get all the triples for the graph.find */
+    public static List<Triple> triples(Graph graph, Node s, Node p, Node o) {
+        List<Triple> acc = new ArrayList<>() ;
         accTriples(acc, graph, s, p, o) ;
         return acc ;
     }
 
-    /* Get all the triples for the graph.find */
-    public static long countTriples(Graph graph, Node s, Node p, Node o)
-    {
+    /* Count the triples for the graph.find */
+    public static long countTriples(Graph graph, Node s, Node p, Node o) {
         ExtendedIterator<Triple> iter = graph.find(s, p, o) ;
         try { return Iter.count(iter) ; }
         finally { iter.close() ; }
     }
 
-    public static void accTriples(Collection<Triple> acc, Graph graph, Node s, 
Node p, Node o)
-    {
+    /* Count the matches to a pattern across the dataset  */
+    public static long countTriples(DatasetGraph dsg, Node s, Node p, Node o) {
+        Iterator<Quad> iter = dsg.find(Node.ANY, s, p, o) ;
+        return Iter.count(iter) ;
+    }
+
+    /** Collect all the matching triples */
+    public static void accTriples(Collection<Triple> acc, Graph graph, Node s, 
Node p, Node o) {
         ExtendedIterator<Triple> iter = graph.find(s, p, o) ;
         for ( ; iter.hasNext() ; )
             acc.add(iter.next()) ;
         iter.close() ;
     }
 
-    /* Get a triple or null. */
-    public static Triple triple1(Graph graph, Node s, Node p, Node o)
-    {
+    /** Get exactly one triple or null for none or more than one. */
+    public static Triple triple1(Graph graph, Node s, Node p, Node o) {
         ExtendedIterator<Triple> iter = graph.find(s, p, o) ;
         try {
-            if ( ! iter.hasNext() )
+            if ( !iter.hasNext() )
                 return null ;
             Triple t = iter.next() ;
-            if (  iter.hasNext() )
+            if ( iter.hasNext() )
                 return null ;
             return t ;
-        } finally { iter.close() ; }
+        }
+        finally {
+            iter.close() ;
+        }
     }
 
-    public static boolean strSafeFor(String str, char ch) { return 
str.indexOf(ch) == -1 ; }
+    /** Get exactly one triple, or null for none or more than one. */
+    public static Triple triple1(DatasetGraph dsg, Node s, Node p, Node o) {
+        Iterator<Quad> iter = dsg.find(Node.ANY, s, p, o) ;
+            if ( !iter.hasNext() )
+                return null ;
+            Quad q = iter.next() ;
+            if ( iter.hasNext() )
+                return null ;
+            return q.asTriple() ;
+    }
 
-    public static void writeBase(IndentedWriter out, String base)
-    {
-        if ( base != null )
-        {
+    public static boolean strSafeFor(String str, char ch) {
+        return str.indexOf(ch) == -1 ;
+    }
+
+    public static void writeBase(IndentedWriter out, String base) {
+        if ( base != null ) {
             out.print("@base ") ;
             out.pad(PREFIX_IRI) ;
             out.print("<") ;
@@ -207,12 +230,9 @@ public class RiotLib
         }
     }
 
-    public static void writePrefixes(IndentedWriter out, PrefixMap prefixMap)
-    {        
-        if ( prefixMap != null && ! prefixMap.isEmpty() )
-        {
-            for ( Map.Entry <String, String> e : 
prefixMap.getMappingCopyStr().entrySet() )
-            {
+    public static void writePrefixes(IndentedWriter out, PrefixMap prefixMap) {
+        if ( prefixMap != null && !prefixMap.isEmpty() ) {
+            for ( Map.Entry<String, String> e : 
prefixMap.getMappingCopyStr().entrySet() ) {
                 out.print("@prefix ") ;
                 out.print(e.getKey()) ;
                 out.print(": ") ;
@@ -287,6 +307,7 @@ public class RiotLib
         return nodeMaxWidth ;
     }
 
+    /** IndentedWriter over a jaav.io.Writer (better to use an IndentedWriter 
over an OutputStream) */
     public static IndentedWriter create(Writer writer)  { return new 
IndentedWriterWriter(writer) ; }
 
     public static PrefixMap prefixMap(Graph graph)      { return 
PrefixMapFactory.create(graph.getPrefixMapping()) ; }
@@ -294,6 +315,7 @@ public class RiotLib
     public static WriterGraphRIOTBase adapter(WriterDatasetRIOT writer)
     { return new WriterAdapter(writer) ; }
 
+    /** Hidden to direct program to using OutputStreams (for RDF, that gets 
the charset right) */ 
     private static class IndentedWriterWriter extends IndentedWriter
     {
         IndentedWriterWriter(Writer w) { super(w) ; }

Modified: 
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/writer/TriGWriter.java
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/writer/TriGWriter.java?rev=1611937&r1=1611936&r2=1611937&view=diff
==============================================================================
--- 
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/writer/TriGWriter.java 
(original)
+++ 
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/writer/TriGWriter.java 
Sat Jul 19 18:02:34 2014
@@ -18,14 +18,18 @@
 
 package org.apache.jena.riot.writer;
 
-import static org.apache.jena.riot.writer.WriterConst.* ;
+import static org.apache.jena.riot.writer.WriterConst.INDENT_GDFT ;
+import static org.apache.jena.riot.writer.WriterConst.INDENT_GNMD ;
+import static org.apache.jena.riot.writer.WriterConst.NL_GDFT_END ;
+import static org.apache.jena.riot.writer.WriterConst.NL_GDFT_START ;
+import static org.apache.jena.riot.writer.WriterConst.NL_GNMD_END ;
+import static org.apache.jena.riot.writer.WriterConst.NL_GNMD_START ;
 
 import java.util.Iterator ;
 
 import org.apache.jena.atlas.io.IndentedWriter ;
 import org.apache.jena.riot.system.PrefixMap ;
 
-import com.hp.hpl.jena.graph.Graph ;
 import com.hp.hpl.jena.graph.Node ;
 import com.hp.hpl.jena.sparql.core.DatasetGraph ;
 import com.hp.hpl.jena.sparql.core.Quad ;
@@ -56,17 +60,17 @@ public class TriGWriter extends TriGWrit
 
             Iterator<Node> graphNames = dsg.listGraphNodes() ;
 
-            writeGraph(null, dsg.getDefaultGraph()) ;
+            writeGraphTriG(dsg, null) ;
 
             for ( ; graphNames.hasNext() ; )
             {
                 out.println() ;
                 Node gn = graphNames.next() ;
-                writeGraph(gn, dsg.getGraph(gn)) ;
+                writeGraphTriG(dsg, gn) ;
             }
         }
 
-        private void writeGraph(Node name, Graph graph)
+        private void writeGraphTriG(DatasetGraph dsg, Node name)
         {
             boolean dftGraph =  ( name == null || name == 
Quad.defaultGraphNodeGenerated  ) ;
             boolean NL_START =  ( dftGraph ? NL_GDFT_START : NL_GNMD_START ) ; 
@@ -85,8 +89,7 @@ public class TriGWriter extends TriGWrit
                 out.print(" ") ;
             
             out.incIndent(INDENT_GRAPH) ;
-            // Pretty Turtle Writer. 
-            writeGraphTTL(graph) ;
+            writeGraphTTL(dsg, name) ;
             out.decIndent(INDENT_GRAPH) ;
             
             if ( NL_END )

Modified: 
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java?rev=1611937&r1=1611936&r2=1611937&view=diff
==============================================================================
--- 
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java 
(original)
+++ 
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java 
Sat Jul 19 18:02:34 2014
@@ -17,13 +17,27 @@
  * limitations under the License.
  */
 
-package org.apache.jena.riot.writer;
+package org.apache.jena.riot.writer ;
 
-import static org.apache.jena.riot.writer.WriterConst.* ;
+import static org.apache.jena.riot.writer.WriterConst.GAP_P_O ;
+import static org.apache.jena.riot.writer.WriterConst.GAP_S_P ;
+import static org.apache.jena.riot.writer.WriterConst.INDENT_OBJECT ;
+import static org.apache.jena.riot.writer.WriterConst.INDENT_PREDICATE ;
+import static org.apache.jena.riot.writer.WriterConst.LONG_PREDICATE ;
+import static org.apache.jena.riot.writer.WriterConst.LONG_SUBJECT ;
+import static org.apache.jena.riot.writer.WriterConst.MIN_PREDICATE ;
+import static org.apache.jena.riot.writer.WriterConst.OBJECT_LISTS ;
+import static org.apache.jena.riot.writer.WriterConst.RDF_First ;
+import static org.apache.jena.riot.writer.WriterConst.RDF_Nil ;
+import static org.apache.jena.riot.writer.WriterConst.RDF_Rest ;
+import static org.apache.jena.riot.writer.WriterConst.RDF_type ;
+import static org.apache.jena.riot.writer.WriterConst.rdfNS ;
 
 import java.util.* ;
 
 import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.lib.Lib ;
 import org.apache.jena.atlas.lib.Pair ;
 import org.apache.jena.riot.other.GLib ;
 import org.apache.jena.riot.out.NodeFormatter ;
@@ -36,144 +50,313 @@ import org.apache.jena.riot.system.RiotL
 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.DatasetGraph ;
+import com.hp.hpl.jena.sparql.core.Quad ;
 import com.hp.hpl.jena.util.iterator.ExtendedIterator ;
 import com.hp.hpl.jena.vocabulary.RDF ;
 import com.hp.hpl.jena.vocabulary.RDFS ;
 
-/** Base class to support the pretty forms of Turtle-related languages 
(Turtle, TriG) */ 
-public abstract class TurtleShell
-{
-    protected final IndentedWriter out ; 
-    protected final NodeFormatter nodeFmt ;
-    protected final PrefixMap prefixMap ;
-    protected final String baseURI ;
+/**
+ * Base class to support the pretty forms of Turtle-related languages (Turtle,
+ * TriG)
+ */
+public abstract class TurtleShell {
+    protected final IndentedWriter out ;
+    protected final NodeFormatter  nodeFmt ;
+    protected final PrefixMap      prefixMap ;
+    protected final String         baseURI ;
 
-    protected TurtleShell(IndentedWriter out, PrefixMap pmap, String baseURI)
-    {
+    protected TurtleShell(IndentedWriter out, PrefixMap pmap, String baseURI) {
         this.out = out ;
         if ( pmap == null )
             pmap = PrefixMapFactory.emptyPrefixMap() ;
-        this.nodeFmt = new NodeFormatterTTL(baseURI,  pmap, 
NodeToLabel.createScopeByDocument()) ;
+        this.nodeFmt = new NodeFormatterTTL(baseURI, pmap, 
NodeToLabel.createScopeByDocument()) ;
         this.prefixMap = pmap ;
         this.baseURI = baseURI ;
     }
 
-    protected void writeBase(String base)
-    {
+    protected void writeBase(String base) {
         RiotLib.writeBase(out, base) ;
     }
 
-    protected void writePrefixes(PrefixMap prefixMap)
-    {
+    protected void writePrefixes(PrefixMap prefixMap) {
         RiotLib.writePrefixes(out, prefixMap) ;
     }
 
-    protected void writeGraphTTL(Graph graph)
-    {
-        ShellGraph x = new ShellGraph(graph) ;
+    /** Write graph in Trutle syntax (or part of TriG) */
+    protected void writeGraphTTL(Graph graph) {
+        ShellGraph x = new ShellGraph(graph, null, null) ;
+        x.writeGraph() ;
+    }    
+
+    /** Write graph in Trutle syntax (or part of TriG). graphName is null for 
default graph. */
+    protected void writeGraphTTL(DatasetGraph dsg, Node graphName) {
+        Graph g = (graphName == null || Quad.isDefaultGraph(graphName)) 
+            ? dsg.getDefaultGraph()
+            : dsg.getGraph(graphName) ; 
+        ShellGraph x = new ShellGraph(g, graphName, dsg) ;
         x.writeGraph() ;
     }
-    
-    // Write one graph - using an inner object class to isolate 
-    // the state variables for writing a single graph. 
+
+    // Write one graph - using an inner object class to isolate
+    // the state variables for writing a single graph.
     private final class ShellGraph {
-        // Per graph member variables.
-        private final Graph graph ; 
-        private final Set<Node> nestedObjects ;           // Blank nodes that 
have one incoming triple
-        private final Set<Node> freeBnodes ;              // Blank nodes 
subjects that are not referenced
-        private final Map<Node, List<Node>> lists;        // The head node in 
each well-formed lists -> list elements 
-        private final Map<Node, List<Node>> freeLists;    // List that do not 
have any incoming triples 
-        private final Map<Node, List<Node>> nLinkedLists; // Lists that have 
more than one incoming triple 
-        private final Collection<Node> listElts ;         // All nodes that 
are part of list structures.
-
-        private ShellGraph(Graph graph)
-        {
-            this.graph          = graph ;
-            this.nestedObjects  = new HashSet<>()  ;
-            this.freeBnodes     = new HashSet<>()  ;
+        // Dataset (for writing graphs indatasets) -- may be null
+        private final DatasetGraph          dsg ;  
+        private final Collection<Node>      graphNames ; 
+        private final Node                  graphName ;
+        private final Graph                 graph ;
+        
+        // Blank nodes that have one incoming triple
+        private final Set<Node>             nestedObjects ; 
+
+        // Blank node subjects that are not referenced as objects or graph 
names
+        // excluding unlnked lists. 
+        private final Set<Node>             freeBnodes ;  
+
+        // The head node in each well-formed list -> list elements
+        private final Map<Node, List<Node>> lists ;   
+
+        // List that do not have any incoming triples
+        private final Map<Node, List<Node>> freeLists ; 
+
+        // Lists that have more than one incoming triple
+        private final Map<Node, List<Node>> nLinkedLists ; 
+
+        // All nodes that are part of list structures.
+        private final Collection<Node>      listElts ;  
+
+        private ShellGraph(Graph graph, Node graphName, DatasetGraph dsg) {
+            this.dsg = dsg ;
+            this.graphName = graphName ;
+            
+            this.graphNames = (dsg != null) ? Iter.toSet(dsg.listGraphNodes()) 
: null ; 
             
-            this.lists          = new HashMap<>() ;
-            this.freeLists      = new HashMap<>() ;
-            this.nLinkedLists   = new HashMap<>() ;
-            this.listElts       = new HashSet<>() ;
+            this.graph = graph ;
+            this.nestedObjects = new HashSet<>() ;
+            this.freeBnodes = new HashSet<>() ;
 
+            this.lists = new HashMap<>() ;
+            this.freeLists = new HashMap<>() ;
+            this.nLinkedLists = new HashMap<>() ;
+            this.listElts = new HashSet<>() ;
+
+            
             // Must be in this order.
             findLists() ;
-            findBNodesSyntax() ;
-            // Stop head of lists printed as triples going all the way to the 
good part. 
+            findBNodesSyntax1() ;
+            // Stop head of lists printed as triples going all the way to the
+            // good part.
             nestedObjects.removeAll(listElts) ;
         }
 
-        /* Bnodes that can written as [] */
-        private void findBNodesSyntax()
-        {
-            Set<Node> rejects = new HashSet<>() ;           // Nodes known not 
to meet the requirement.
+        private ShellGraph(Graph graph) {
+            this(graph, null, null) ;
+        }
+
+        // ---- Data access
+        /** Get all the triples for the graph.find */
+        private List<Triple> triples(Node s, Node p, Node o) {
+            List<Triple> acc = new ArrayList<>() ;
+            RiotLib.accTriples(acc, graph, s, p, o) ;
+            return acc ;
+        }
+
+        /** Get exactly one triple or null for none or more than one. */
+        private Triple triple1(Node s, Node p, Node o) {
+            if ( dsg != null )
+                return RiotLib.triple1(dsg, s, p, o) ;
+            else
+                return RiotLib.triple1(graph, s, p, o) ;
+        }
 
-            ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, 
Node.ANY) ;
+        /** Get exactly one triple, or null for none or more than one. */
+        private Triple triple1(DatasetGraph dsg, Node s, Node p, Node o) {
+            Iterator<Quad> iter = dsg.find(Node.ANY, s, p, o) ;
+            if ( !iter.hasNext() )
+                return null ;
+            Quad q = iter.next() ;
+            if ( iter.hasNext() )
+                return null ;
+            return q.asTriple() ;
+        }
+
+        private long countTriples(Node s, Node p, Node o) {
+            if ( dsg != null )
+                return RiotLib.countTriples(dsg, s, p, o) ;
+            else
+                return RiotLib.countTriples(graph, s, p, o) ;
+        }
+
+        private ExtendedIterator<Triple> find(Node s, Node p, Node o) {
+            return graph.find(s, p, o) ;
+        }
+
+        /** returns 0,1,2 (where 2 really means "more than 1") */
+        private int inLinks(Node obj) {
+            if ( dsg != null ) {
+                Iterator<Quad> iter = dsg.find(Node.ANY, Node.ANY, Node.ANY, 
obj) ;
+                return count012(iter) ;
+            } else {
+                ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, 
obj) ;
+                try { return count012(iter) ; }
+                finally { iter.close() ; }
+            }
+        }
+
+        /** returns 0,1,2 (where 2 really means "more than 1") */
+        private int occursAsSubject(Node subj) {
+            if ( dsg != null ) {
+                Iterator<Quad> iter = dsg.find(Node.ANY, subj, Node.ANY, 
Node.ANY) ;
+                return count012(iter) ;
+            } else {
+                ExtendedIterator<Triple> iter = graph.find(subj, Node.ANY, 
Node.ANY) ;
+                try { return count012(iter) ; }
+                finally { iter.close() ; }
+            }
+        }
+        
+        private int count012(Iterator<? > iter) {
+            if ( !iter.hasNext() )
+                return 0 ;
+            iter.next() ;
+            if ( !iter.hasNext() )
+                return 1 ;
+            return 2 ;
+        }
+
+        /** Check whether a node is used only in the graph we're working on */ 
+        private boolean containedInOneGraph(Node node) {
+            if ( dsg == null )
+                // Single graph
+                return true ;
+            
+            if ( graphNames.contains(node) )
+                // Used as a graph name.
+                return false ;
+            
+            Iterator<Quad> iter = dsg.find(Node.ANY, node, Node.ANY, Node.ANY) 
;
+            if ( ! quadsThisGraph(iter) ) 
+                return false ;
+
+            iter = dsg.find(Node.ANY, Node.ANY, node, Node.ANY) ;
+            if ( ! quadsThisGraph(iter) ) 
+                return false ;
+            
+            iter = dsg.find(Node.ANY, Node.ANY, Node.ANY, node) ;
+            if ( ! quadsThisGraph(iter) ) 
+                return false ;
+            return true ;
+        }
+
+        /** Check whether an iterator of quads is all in the same graph 
(dataset assumed) */ 
+        private boolean quadsThisGraph(Iterator<Quad> iter) {
+            if ( ! iter.hasNext() )
+                // Empty iterator
+                return true ;
+            Quad q = iter.next() ;
+            Node gn = q.getGraph() ;
+
+            // Test first quad - both default graph (various forms) or same 
named graph
+            if ( isDefaultGraph(gn) ) {
+                if ( ! isDefaultGraph(graphName) )
+                    return false ;
+            } else { 
+                if ( ! Lib.equal(gn, graphName) )
+                    // Not both same named graph
+                    return false ;
+            }
+            // Check rest of iterator.
+            for ( ; iter.hasNext() ; ) {
+                Quad q2 = iter.next() ;
+                if ( ! Lib.equal(gn, q2.getGraph()) )
+                    return false ;    
+            }
+            return true ;
+        }
+        
+        private boolean isDefaultGraph(Node node) {
+            return node == null || Quad.isDefaultGraph(node) ;
+        }
+        
+        /** Get triples with the same subject */
+        private Collection<Triple> triplesOfSubject(Node subj) {
+            return RiotLib.triplesOfSubject(graph, subj) ;
+        }
+
+        private Iterator<Node> listSubjects() {
+            return GLib.listSubjects(graph) ;
+        }
+
+        // ---- Data access
+
+        /** Find Bnodes that can written as []
+         * Subject position (top level) - only used for subject position 
anywhere in the dataset
+         * Object position (any level) - only used as object once anywhere in 
the dataset
+         */
+        private void findBNodesSyntax1() {
+            Set<Node> rejects = new HashSet<>() ; // Nodes known not to meet 
the requirement.
+
+            ExtendedIterator<Triple> iter = find(Node.ANY, Node.ANY, Node.ANY) 
;
             try {
                 for ( ; iter.hasNext() ; )
                 {
                     Triple t = iter.next() ;
                     Node subj = t.getSubject() ;
-                    if ( subj.isBlank() && ! lists.containsKey(subj))
+                    Node obj = t.getObject() ;
+                    if ( listElts.contains(subj) )  // In a list?
+                        continue ;
+                    if ( listElts.contains(obj) )  // In a list?
+                        continue ;
+                    
+                    if ( subj.isBlank() )
                     {
-                        // And not a list ...
+                        // Blank node, not a list ...
                         int sConn = inLinks(subj) ;
-                        if ( sConn == 0 )
+                        if ( sConn == 0 && containedInOneGraph(subj) )  
+                            // Not used as an object in this graph.
                             freeBnodes.add(subj) ;
                     }
                     
-                    Node obj = t.getObject() ;
                     if ( ! obj.isBlank() )
                         continue ;
                     if ( rejects.contains(obj) )
                         continue ;
-                    // No point checking bNodesObj1.
+
                     int connectivity = inLinks(obj) ;
-                    if ( connectivity == 1 )
+                    if ( connectivity == 1 && containedInOneGraph(obj) ) {
+                        // If not used in another graph (or as graph name)
                         nestedObjects.add(obj) ;
-                    // else connected multiple times.
+                    }
+                    else
+                        // Uninteresting object connected multiple times. 
+                        rejects.add(obj) ;
                 }
             } finally { iter.close() ; }
         }
-
-        // returns 0,1,2 (where 2 really means "more than 1")
-        private int inLinks(Node obj)
-        {
-            ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, 
obj) ;
-            int count = 0 ;
-            try {
-                if ( ! iter.hasNext() ) return 0 ;
-                iter.next() ;
-                if ( ! iter.hasNext() ) return 1 ;
-                return 2 ;
-            } finally { iter.close() ; }
-        }
-
+        
         // --- Lists setup
-        /* Find all list heads and all nodes in well-formed lists.
-         * Return a (list head -> Elements map), list elements)  
+        /*
+         * Find all list heads and all nodes in well-formed lists. Return a
+         * (list head -> Elements map), list elements)
          */
-        private void findLists()
-        {
-            List<Triple> tails = RiotLib.triples(graph, Node.ANY, RDF_Rest, 
RDF_Nil) ;
-            for ( Triple t : tails )
-            {
+        private void findLists() {
+            List<Triple> tails = triples(Node.ANY, RDF_Rest, RDF_Nil) ;
+            for ( Triple t : tails ) {
                 // Returns the elements, reversed.
                 Collection<Node> listElts2 = new HashSet<>() ;
                 Pair<Node, List<Node>> p = followTailToHead(t.getSubject(), 
listElts2) ;
-                if ( p != null )
-                {
-                    Node headElt = p.getLeft() ; 
-                    // Free standing?private
+                if ( p != null ) {
+                    Node headElt = p.getLeft() ;
+                    // Free standing/private
                     List<Node> elts = p.getRight() ;
-                    long numLinks = RiotLib.countTriples(graph, null, null, 
headElt) ;
+                    long numLinks = countTriples(null, null, headElt) ;
                     if ( numLinks == 1 )
                         lists.put(headElt, elts) ;
                     else if ( numLinks == 0 )
                         // 0 connected lists
                         freeLists.put(headElt, elts) ;
-                    else 
+                    else
                         // Two triples to this list.
                         nLinkedLists.put(headElt, elts) ;
                     listElts.addAll(listElts2) ;
@@ -182,36 +365,32 @@ public abstract class TurtleShell
         }
 
         // return head elt node, list of elements.
-        private Pair<Node, List<Node>> followTailToHead(Node lastListElt, 
Collection<Node> listElts)
-        {
+        private Pair<Node, List<Node>> followTailToHead(Node lastListElt, 
Collection<Node> listElts) {
             List<Node> listCells = new ArrayList<>() ;
             List<Node> eltsReversed = new ArrayList<>() ;
-            List<Triple> acc =  new ArrayList<>() ;
+            List<Triple> acc = new ArrayList<>() ;
             Node x = lastListElt ;
 
-            for ( ; ; )
-            {
-                if ( ! validListElement(x, acc) )
-                {
+            for ( ; ; ) {
+                if ( !validListElement(x, acc) ) {
                     if ( listCells.size() == 0 )
                         // No earlier valid list.
                         return null ;
                     // Fix up to previous valid list cell.
-                    x = listCells.remove(listCells.size()-1) ;
+                    x = listCells.remove(listCells.size() - 1) ;
                     break ;
                 }
 
-                Triple t = RiotLib.triple1(graph, x, RDF_First, null) ;
+                Triple t = triple1(x, RDF_First, null) ;
                 if ( t == null )
                     return null ;
                 eltsReversed.add(t.getObject()) ;
                 listCells.add(x) ;
 
                 // Try to move up the list.
-                List<Triple> acc2 = RiotLib.triples(graph, null, null, x) ;
-                long numRest = RiotLib.countTriples(graph, null, RDF_Rest, x) ;
-                if ( numRest != 1 )
-                {
+                List<Triple> acc2 = triples(null, null, x) ;
+                long numRest = countTriples(null, RDF_Rest, x) ;
+                if ( numRest != 1 ) {
                     // Head of well-formed list.
                     // Classified by 0,1,more links later.
                     listCells.add(x) ;
@@ -229,19 +408,19 @@ public abstract class TurtleShell
             // Success.
             listElts.addAll(listCells) ;
             Collections.reverse(eltsReversed) ;
-            return Pair.create(x, eltsReversed);
+            return Pair.create(x, eltsReversed) ;
         }
 
-        /* Return the triples of the list element, or null if invalid list */
-        private boolean validListElement(Node x, List<Triple> acc)
-        {
-            Triple t1 = RiotLib.triple1(graph, x, RDF_Rest, null) ; // Which 
we came up to get here :-(
+        /** Return the triples of the list element, or null if invalid list */
+        private boolean validListElement(Node x, List<Triple> acc) {
+            Triple t1 = triple1(x, RDF_Rest, null) ; // Which we came up to get
+                                                     // here :-(
             if ( t1 == null )
                 return false ;
-            Triple t2 = RiotLib.triple1(graph, x, RDF_First, null) ;
+            Triple t2 = triple1(x, RDF_First, null) ;
             if ( t2 == null )
                 return false ;
-            long N = RiotLib.countTriples(graph, x, null, null) ;
+            long N = countTriples(x, null, null) ;
             if ( N != 2 )
                 return false ;
             acc.add(t1) ;
@@ -251,33 +430,31 @@ public abstract class TurtleShell
 
         // ----
 
-        private void writeGraph()
-        {
-            Iterator<Node> subjects = GLib.listSubjects(graph) ;
+        private void writeGraph() {
+            Iterator<Node> subjects = listSubjects() ;
             boolean somethingWritten = writeBySubject(subjects) ;
 
             // Write remainders
             // 1 - Shared lists
             // 2 - Free standing lists
-            
-            if ( ! nLinkedLists.isEmpty() )
+
+            if ( !nLinkedLists.isEmpty() )
                 somethingWritten = writeNLinkedLists(somethingWritten) ;
-            
-            if ( ! freeLists.isEmpty() )
+
+            if ( !freeLists.isEmpty() )
                 somethingWritten = writeFreeLists(somethingWritten) ;
-            
-                
+
         }
 
-        // Write lists that are shared objects  
-        private boolean writeNLinkedLists(boolean somethingWritten)
-        {
+        // Write lists that are shared objects
+        private boolean writeNLinkedLists(boolean somethingWritten) {
             // Print carefully - need a label for the first cell.
-            // So we write out the first element of the list in triples, then 
put
+            // So we write out the first element of the list in triples, then
+            // put
             // the remainer as a pretty list
-            for ( Node n : nLinkedLists.keySet() )
-            {
-                if ( somethingWritten ) out.println() ;
+            for ( Node n : nLinkedLists.keySet() ) {
+                if ( somethingWritten )
+                    out.println() ;
                 somethingWritten = true ;
 
                 List<Node> x = nLinkedLists.get(n) ;
@@ -307,14 +484,14 @@ public abstract class TurtleShell
             return somethingWritten ;
         }
 
-        // Write free standing lists - ones where the head is not an object of 
some other triple.
-        // Turtle does not (... ) . so write as a predicateObjectList for one 
element. 
-        private boolean writeFreeLists(boolean somethingWritten)
-        {
-            //out.println("# Free standing lists") ;
+        // Write free standing lists - ones where the head is not an object of
+        // some other triple.
+        // Turtle does not (... ) . so write as a predicateObjectList for one
+        // element.
+        private boolean writeFreeLists(boolean somethingWritten) {
+            // out.println("# Free standing lists") ;
             // Write free lists.
-            for ( Node n : freeLists.keySet() )
-            {
+            for ( Node n : freeLists.keySet() ) {
                 if ( somethingWritten )
                     out.println() ;
                 somethingWritten = true ;
@@ -338,44 +515,40 @@ public abstract class TurtleShell
         }
 
         // return true if did write something.
-        private boolean writeBySubject(Iterator<Node> subjects)
-        {
+        private boolean writeBySubject(Iterator<Node> subjects) {
             boolean first = true ;
-            for ( ; subjects.hasNext() ; )
-            {
+            for ( ; subjects.hasNext() ; ) {
                 Node subj = subjects.next() ;
                 if ( nestedObjects.contains(subj) )
                     continue ;
-                
+
                 if ( listElts.contains(subj) )
                     continue ;
-                if ( ! first ) 
+                if ( !first )
                     out.println() ;
                 first = false ;
-                if ( freeBnodes.contains(subj) ) 
-                {
+                if ( freeBnodes.contains(subj) ) {
                     // Write in "[....]" form.
                     nestedObject(subj) ;
                     out.println(" .") ;
                     continue ;
                 }
 
-                Collection<Triple> cluster = RiotLib.triplesOfSubject(graph, 
subj) ;
+                Collection<Triple> cluster = triplesOfSubject(subj) ;
                 writeCluster(subj, cluster) ;
             }
             return !first ;
         }
 
-
         // Common subject
         // Used by the blocks writer as well.
-        private void writeCluster(Node subject, Collection<Triple> cluster)
-        {
-            if ( cluster.isEmpty() ) return ;
+        private void writeCluster(Node subject, Collection<Triple> cluster) {
+            if ( cluster.isEmpty() )
+                return ;
             writeNode(subject) ;
 
             if ( out.getCol() > LONG_SUBJECT )
-                out.println() ; 
+                out.println() ;
             else
                 gap(GAP_S_P) ;
             out.incIndent(INDENT_PREDICATE) ;
@@ -384,163 +557,151 @@ public abstract class TurtleShell
             out.decIndent(INDENT_PREDICATE) ;
             // End of cluster.
             print(" .") ;
-            println() ; 
+            println() ;
         }
 
         // Writing predciate-object lists.
         // We group the cluster by predicate and within each group
         // we print:
-        //  literals, then simple objects, then pretty objects 
-        
-        private void writePredicateObjectList(Collection<Triple> cluster)
-        {
+        // literals, then simple objects, then pretty objects
+
+        private void writePredicateObjectList(Collection<Triple> cluster) {
             Map<Node, List<Node>> pGroups = groupByPredicates(cluster) ;
             Collection<Node> predicates = pGroups.keySet() ;
-            
+
             // Find longest predicate URI
             int predicateMaxWidth = RiotLib.calcWidth(prefixMap, baseURI, 
predicates, MIN_PREDICATE, LONG_PREDICATE) ;
 
             boolean first = true ;
 
-            if ( ! OBJECT_LISTS )
-            {
-                for ( Node p : predicates )
-                {
-                    for ( Node o : pGroups.get(p) )
-                    {
+            if ( !OBJECT_LISTS ) {
+                for ( Node p : predicates ) {
+                    for ( Node o : pGroups.get(p) ) {
                         writePredicateObject(p, o, predicateMaxWidth, first) ;
                         first = false ;
                     }
                 }
                 return ;
             }
-            
-            for ( Node p : predicates )
-            {
-                List<Node> rdfLiterals = new ArrayList<>() ;        // 
Literals in the group
-                List<Node> rdfSimpleNodes = new ArrayList<>() ;     // 
Non-literals, printed
-                List<Node> rdfComplexNodes = new ArrayList<>() ;    // 
Non-literals, printed () or []-embedded
 
-                for ( Node o : pGroups.get(p) )
-                {
-                    if ( o.isLiteral() ) { rdfLiterals.add(o) ; continue ; }
-                    if ( isPrettyNode(o) ) { rdfComplexNodes.add(o) ; continue 
; }
+            for ( Node p : predicates ) {
+                List<Node> rdfLiterals = new ArrayList<>() ; // Literals in the
+                                                             // group
+                List<Node> rdfSimpleNodes = new ArrayList<>() ; // 
Non-literals,
+                                                                // printed
+                List<Node> rdfComplexNodes = new ArrayList<>() ; // 
Non-literals,
+                                                                 // printed ()
+                                                                 // or
+                                                                 // []-embedded
+
+                for ( Node o : pGroups.get(p) ) {
+                    if ( o.isLiteral() ) {
+                        rdfLiterals.add(o) ;
+                        continue ;
+                    }
+                    if ( isPrettyNode(o) ) {
+                        rdfComplexNodes.add(o) ;
+                        continue ;
+                    }
                     rdfSimpleNodes.add(o) ;
                 }
-                
-                if ( rdfLiterals.size() != 0 )
-                {
+
+                if ( rdfLiterals.size() != 0 ) {
                     writePredicateObjectList(p, rdfLiterals, 
predicateMaxWidth, first) ;
                     first = false ;
                 }
-                if ( rdfSimpleNodes.size() != 0 )
-                {
+                if ( rdfSimpleNodes.size() != 0 ) {
                     writePredicateObjectList(p, rdfSimpleNodes, 
predicateMaxWidth, first) ;
                     first = false ;
                 }
-                
-                for ( Node o : rdfComplexNodes )
-                {
+
+                for ( Node o : rdfComplexNodes ) {
                     writePredicateObject(p, o, predicateMaxWidth, first) ;
                     first = false ;
                 }
             }
         }
-        
-        private void writePredicateObject(Node p, Node obj, int 
predicateMaxWidth, boolean first)
-        {
+
+        private void writePredicateObject(Node p, Node obj, int 
predicateMaxWidth, boolean first) {
             writePredicate(p, predicateMaxWidth, first) ;
-            out.incIndent(INDENT_OBJECT) ;  
+            out.incIndent(INDENT_OBJECT) ;
             writeNodePretty(obj) ;
             out.decIndent(INDENT_OBJECT) ;
         }
 
-        private void writePredicateObjectList(Node p, List<Node> objects, int 
predicateMaxWidth, boolean first)
-        {
+        private void writePredicateObjectList(Node p, List<Node> objects, int 
predicateMaxWidth, boolean first) {
             writePredicate(p, predicateMaxWidth, first) ;
-            out.incIndent(INDENT_OBJECT) ;  
+            out.incIndent(INDENT_OBJECT) ;
             boolean firstObject = true ;
-            for ( Node o : objects) 
-            {
-                if ( ! firstObject )
+            for ( Node o : objects ) {
+                if ( !firstObject )
                     out.print(" , ") ;
                 else
-                    firstObject = false ; 
+                    firstObject = false ;
                 writeNode(o) ;
-                //writeNodePretty(obj) ;
+                // writeNodePretty(obj) ;
             }
             out.decIndent(INDENT_OBJECT) ;
         }
-    
-            
-        /** Write a predicate - jump to next line if deemed long */   
-        private void writePredicate(Node p, int predicateMaxWidth, boolean 
first)
-        {
+
+        /** Write a predicate - jump to next line if deemed long */
+        private void writePredicate(Node p, int predicateMaxWidth, boolean 
first) {
             if ( first )
                 first = false ;
-            else
-            {
+            else {
                 print(" ;") ;
                 println() ;
             }
             int colPredicateStart = out.getAbsoluteIndent() ;
-            
-            if ( ! prefixMap.contains(rdfNS) && RDF_type.equals(p) )
+
+            if ( !prefixMap.contains(rdfNS) && RDF_type.equals(p) )
                 print("a") ;
             else
                 writeNode(p) ;
             int colPredicateFinish = out.getCol() ;
-            int wPredicate = (colPredicateFinish-colPredicateStart) ;
+            int wPredicate = (colPredicateFinish - colPredicateStart) ;
 
             if ( wPredicate > LONG_PREDICATE )
                 println() ;
-            else
-            {
+            else {
                 out.pad(predicateMaxWidth) ;
-                //out.print(' ', predicateMaxWidth-wPredicate) ;
+                // out.print(' ', predicateMaxWidth-wPredicate) ;
                 gap(GAP_P_O) ;
             }
         }
-            
-        private Map<Node, List<Node>> groupByPredicates(Collection<Triple> 
cluster)
-        {
+
+        private Map<Node, List<Node>> groupByPredicates(Collection<Triple> 
cluster) {
             SortedMap<Node, List<Node>> x = new TreeMap<>(compPredicates) ;
-            for ( Triple t : cluster )
-            {
+            for ( Triple t : cluster ) {
                 Node p = t.getPredicate() ;
-                if ( ! x.containsKey(p) )
+                if ( !x.containsKey(p) )
                     x.put(p, new ArrayList<Node>()) ;
                 x.get(p).add(t.getObject()) ;
             }
-            
+
             return x ;
         }
 
-        private int countPredicates(Collection<Triple> cluster)
-        {
+        private int countPredicates(Collection<Triple> cluster) {
             Set<Node> x = new HashSet<>() ;
-            for ( Triple t : cluster )
-            {
+            for ( Triple t : cluster ) {
                 Node p = t.getPredicate() ;
                 x.add(p) ;
             }
             return x.size() ;
         }
 
-        private void nestedObject(Node node)
-        {
-            Collection<Triple> x = RiotLib.triplesOfSubject(graph, node) ;
+        private void nestedObject(Node node) {
+            Collection<Triple> x = triplesOfSubject(node) ;
 
-            if ( x.isEmpty() )
-            {
+            if ( x.isEmpty() ) {
                 print("[] ") ;
                 return ;
             }
 
             int pCount = countPredicates(x) ;
-            
-            if ( pCount == 1 )
-            {
+
+            if ( pCount == 1 ) {
                 print("[ ") ;
                 out.incIndent(2) ;
                 writePredicateObjectList(x) ;
@@ -557,52 +718,47 @@ public abstract class TurtleShell
             out.incIndent(2) ;
             writePredicateObjectList(x) ;
             out.decIndent(2) ;
-            if ( true )
-            {
+            if ( true ) {
                 println() ; // Newline for "]"
                 print("]") ;
-            }
-            else
-            {   // Compact
+            } else { // Compact
                 print(" ]") ;
             }
             out.setAbsoluteIndent(indent0) ;
         }
-        
+
         // Write a list
-        private void list(List<Node> elts)
-        {
-            if ( elts.size() == 0 )
-            {
+        private void list(List<Node> elts) {
+            if ( elts.size() == 0 ) {
                 out.print("()") ;
                 return ;
             }
-            
+
             out.print("(") ;
-            for ( Node n : elts )
-            {
+            for ( Node n : elts ) {
                 out.print(" ") ;
                 writeNodePretty(n) ;
             }
 
             out.print(" )") ;
         }
-        
-        private boolean isPrettyNode(Node n)
-        {
+
+        private boolean isPrettyNode(Node n) {
             // Order matters? - one connected objects may include list 
elements.
-            if ( lists.containsKey(n) ) return true ; 
-            if ( nestedObjects.contains(n) ) return true ;
-            if ( RDF_Nil.equals(n) ) return true ;
+            if ( lists.containsKey(n) )
+                return true ;
+            if ( nestedObjects.contains(n) )
+                return true ;
+            if ( RDF_Nil.equals(n) )
+                return true ;
             return false ;
         }
-        
+
         // --> write S or O??
-        private void writeNodePretty(Node obj)
-        {
+        private void writeNodePretty(Node obj) {
             // Order matters? - one connected objects may include list 
elements.
             if ( lists.containsKey(obj) )
-                list(lists.get(obj)) ; 
+                list(lists.get(obj)) ;
             else if ( nestedObjects.contains(obj) )
                 nestedObject(obj) ;
             else if ( RDF_Nil.equals(obj) )
@@ -611,69 +767,60 @@ public abstract class TurtleShell
                 writeNode(obj) ;
         }
     }
-    
-    
+
     // Order of properties.
     // rdf:type ("a")
     // RDF and RDFS
     // Other.
-    //   Sorted by URI.
-    
-    private static final class ComparePredicates implements Comparator<Node>
-    {
-        private static int classification(Node p)
-        {
+    // Sorted by URI.
+
+    private static final class ComparePredicates implements Comparator<Node> {
+        private static int classification(Node p) {
             if ( p.equals(RDF_type) )
-                return 0 ; 
-            
-            if ( p.getURI().startsWith(RDF.getURI()) ||  
-                 p.getURI().startsWith(RDFS.getURI()) )
+                return 0 ;
+
+            if ( p.getURI().startsWith(RDF.getURI()) || 
p.getURI().startsWith(RDFS.getURI()) )
                 return 1 ;
-            
+
             return 2 ;
         }
 
         @Override
-        public int compare(Node t1, Node t2)
-        {
-            int class1 = classification(t1) ; 
-            int class2 = classification(t2) ; 
-            if ( class1 != class2 )
-            {
+        public int compare(Node t1, Node t2) {
+            int class1 = classification(t1) ;
+            int class2 = classification(t2) ;
+            if ( class1 != class2 ) {
                 // Java 1.7
-                //return Integer.compare(class1, class2) ;
-                if ( class1 < class2 ) return -1 ;
-                if ( class1 > class2 ) return 1 ;
+                // return Integer.compare(class1, class2) ;
+                if ( class1 < class2 )
+                    return -1 ;
+                if ( class1 > class2 )
+                    return 1 ;
                 return 0 ;
-             }   
+            }
             String p1 = t1.getURI() ;
             String p2 = t2.getURI() ;
-            return p1.compareTo(p2) ; 
+            return p1.compareTo(p2) ;
         }
     }
 
     private static Comparator<Node> compPredicates = new ComparePredicates() ;
-    
-    protected final void writeNode(Node node)
-    {
+
+    protected final void writeNode(Node node) {
         nodeFmt.format(out, node) ;
     }
 
-    private void print(String x)
-    {
+    private void print(String x) {
         out.print(x) ;
     }
 
-    private void gap(int gap)
-    {
+    private void gap(int gap) {
         out.print(' ', gap) ;
     }
 
     // flush aggressively (debugging)
-    private void println()
-    {
+    private void println() {
         out.println() ;
-        //out.flush() ;
+        // out.flush() ;
     }
 }
-

Modified: 
jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRiotWriterDataset.java
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRiotWriterDataset.java?rev=1611937&r1=1611936&r2=1611937&view=diff
==============================================================================
--- 
jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRiotWriterDataset.java
 (original)
+++ 
jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRiotWriterDataset.java
 Sat Jul 19 18:02:34 2014
@@ -31,6 +31,7 @@ import org.junit.runners.Parameterized.P
 
 import com.hp.hpl.jena.query.Dataset ;
 import com.hp.hpl.jena.query.DatasetFactory ;
+import com.hp.hpl.jena.sparql.util.IsoMatcher ;
 
 @RunWith(Parameterized.class)
 public class TestRiotWriterDataset extends AbstractWriterTest
@@ -65,6 +66,18 @@ public class TestRiotWriterDataset exten
     @Test public void writer03() { test("writer-rt-23.trig") ; }
     @Test public void writer04() { test("writer-rt-24.trig") ; }
     
+    @Test public void writer05() { test("writer-rt-25.trig") ; }
+    @Test public void writer06() { test("writer-rt-26.trig") ; }
+    @Test public void writer07() { test("writer-rt-27.trig") ; }
+    @Test public void writer08() {
+        if ( format.getLang().equals(Lang.JSONLD) )
+            // Broken for JSON-LD (json-ld-java 0.5.0)
+            return ;
+        test("writer-rt-28.trig") ;
+    }    
+    @Test public void writer09() { test("writer-rt-29.trig") ; }
+    @Test public void writer10() { test("writer-rt-30.trig") ; }
+    
     private void test(String filename)
     {
         String displayname = filename.substring(0, filename.lastIndexOf('.')) ;
@@ -96,6 +109,23 @@ public class TestRiotWriterDataset exten
             System.out.println(s) ;
             throw ex ;
         }
+        
+        boolean b = IsoMatcher.isomorphic(ds.asDatasetGraph(), 
ds2.asDatasetGraph()) ;
+        if ( ! b ) {
+            System.out.println("Test: "+format.toString()) ;
+            System.out.println("-- Input") ;
+            RDFDataMgr.write(System.out, ds.asDatasetGraph(), Lang.NQUADS ) ;
+            System.out.println("-- Written") ;
+            System.out.println(s);
+            System.out.println();
+            System.out.println("-- Seen as") ;
+            RDFDataMgr.write(System.out, ds2.asDatasetGraph(), Lang.NQUADS ) ;
+            System.out.println("-------------") ;
+        }
+        
+        assertTrue("Datasets are not isomorphic", b) ;
+        //**** Test ds2 iso ds
+        
     }
 }
 

Added: jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-25.trig
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-25.trig?rev=1611937&view=auto
==============================================================================
--- jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-25.trig (added)
+++ jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-25.trig Sat Jul 19 
18:02:34 2014
@@ -0,0 +1,5 @@
+# Shared bnodes across graphs
+
+prefix : <http://www.example.com/>
+_:b :p :o1 .
+:G { _:b :p :o2 }
\ No newline at end of file

Added: jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-26.trig
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-26.trig?rev=1611937&view=auto
==============================================================================
--- jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-26.trig (added)
+++ jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-26.trig Sat Jul 19 
18:02:34 2014
@@ -0,0 +1,5 @@
+# Shared bnodes across graphs
+prefix : <http://www.example.com/>
+
+:G1 { _:b :p :o1 }
+:G2 { _:b :p :o2 }

Added: jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-27.trig
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-27.trig?rev=1611937&view=auto
==============================================================================
--- jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-27.trig (added)
+++ jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-27.trig Sat Jul 19 
18:02:34 2014
@@ -0,0 +1,5 @@
+prefix : <http://www.example.com/>
+
+_:b { _:b :p :o1 }
+_:z { _:b :p :o2 }
+

Added: jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-28.trig
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-28.trig?rev=1611937&view=auto
==============================================================================
--- jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-28.trig (added)
+++ jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-28.trig Sat Jul 19 
18:02:34 2014
@@ -0,0 +1,36 @@
+# Lists across graphs
+PREFIX :        <http://www.example.com/>
+PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
+
+:x :q _:x0 .
+
+_:x0   rdf:first "cell-0" .
+_:x0   rdf:rest  _:x1 .
+
+_:x1   rdf:first "cell-1" .
+_:x1   rdf:rest  _:x2 .
+
+_:x2   rdf:first "cell-2" .
+_:x2   rdf:rest  rdf:nil .
+
+
+:G {
+  :z :q _:z0 .
+
+  _:z0   rdf:first "cell-A" .
+  _:z0   rdf:rest  _:z1 .
+
+  _:z1   rdf:first "cell-B" .
+  _:z1   rdf:rest  _:z2 .
+
+  _:z2   rdf:first "cell-C" .
+  _:z2   rdf:rest  rdf:nil .
+
+}
+
+# Connect to list above.
+:G1 { _:x1 :other :other }
+
+# Connect to list above.
+:G2 { _:z1 :other :other }
+

Added: jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-29.trig
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-29.trig?rev=1611937&view=auto
==============================================================================
--- jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-29.trig (added)
+++ jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-29.trig Sat Jul 19 
18:02:34 2014
@@ -0,0 +1,9 @@
+# Bnode across graphs blocking use of []
+
+PREFIX :        <http://www.example.com/>
+
+:G1 { 
+    _:x1 :p :o1 . 
+    [ :q 23 ] 
+}
+:G2 { :z :p _:x1  }

Added: jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-30.trig
URL: 
http://svn.apache.org/viewvc/jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-30.trig?rev=1611937&view=auto
==============================================================================
--- jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-30.trig (added)
+++ jena/trunk/jena-arq/testing/RIOT/Writer/writer-rt-30.trig Sat Jul 19 
18:02:34 2014
@@ -0,0 +1,14 @@
+# BNode as graph name blocking use of []
+
+PREFIX :        <http://www.example.com/>
+
+_:x1 :p :o1 . 
+_:x1 { :z :p 1 }
+
+_:x2 { :s :p :o }
+
+:G3 { :z :p _:x2 . 
+     _:x2 :q 123 .
+    }
+
+


Reply via email to