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 2013/03/05 00:22:55 UTC

svn commit: r1452591 [3/4] - in /jena/branches/arq-riot-output: src-examples/arq/examples/riot/ src-examples/arq/examples/update/ src/main/java/com/hp/hpl/jena/sparql/engine/binding/ src/main/java/com/hp/hpl/jena/sparql/engine/optimizer/ src/main/java/...

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/system/RiotWriterLib.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/system/RiotWriterLib.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/system/RiotWriterLib.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/system/RiotWriterLib.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,221 @@
+/**
+ * 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 org.apache.jena.riot.system;
+
+import static org.apache.jena.riot.writer.WriterConst.PREFIX_IRI ;
+import static org.apache.jena.riot.writer.WriterConst.RDF_type ;
+import static org.apache.jena.riot.writer.WriterConst.rdfNS ;
+
+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 org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.WriterDatasetRIOT ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.PrefixMapFactory ;
+import org.apache.jena.riot.writer.WriterGraphRIOTBase ;
+
+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.DatasetGraphFactory ;
+import com.hp.hpl.jena.sparql.util.Context ;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator ;
+
+/** Support code for the RIOT */ 
+public class RiotWriterLib
+{
+    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<Triple>() ;
+        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)
+    {
+        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)
+    {
+        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)
+    {
+        ExtendedIterator<Triple> iter = graph.find(s, p, o) ;
+        try {
+            if ( ! iter.hasNext() )
+                return null ;
+            Triple t = iter.next() ;
+            if (  iter.hasNext() )
+                return null ;
+            return t ;
+        } finally { iter.close() ; }
+    }
+
+    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("<") ;
+            out.print(base) ;
+            out.print(">") ;
+            out.print(" .") ;
+            out.println() ;
+        }
+    }
+    
+    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(": ") ;
+                out.pad(PREFIX_IRI) ;
+                out.print("<") ;
+                out.print(e.getValue()) ;
+                out.print(">") ;
+                out.print(" .") ;
+                out.println() ;
+            }
+        }
+    }
+
+    /** Returns dataset that wraps a graph */
+    public static DatasetGraph dataset(Graph graph)
+    {
+        return DatasetGraphFactory.createOneGraph(graph) ;
+    }        
+    
+    public static PrefixMap prefixMap(DatasetGraph dsg)
+    {
+        return PrefixMapFactory.create(dsg.getDefaultGraph().getPrefixMapping()) ;
+    }
+    
+    private static int calcWidth(PrefixMap prefixMap, String baseURI, Node p)
+    {
+        if ( ! prefixMap.contains(rdfNS) && RDF_type.equals(p) )
+            return 1 ;
+        
+        String x = prefixMap.abbreviate(p.getURI()) ;
+        if ( x == null )
+            return p.getURI().length()+2 ;
+        return x.length() ;
+    }
+    
+    public static int calcWidth(PrefixMap prefixMap, String baseURI, Collection<Node> nodes, int minWidth, int maxWidth)
+    {
+        Node prev = null ; 
+        int nodeMaxWidth = minWidth ;
+        
+        for ( Node n : nodes )
+        {
+            if ( prev != null && prev.equals(n) )
+                continue ;
+            int len = calcWidth(prefixMap, baseURI, n) ;
+            if ( len > maxWidth )
+                continue ;
+            if ( nodeMaxWidth < len )
+                nodeMaxWidth = len ;
+            prev = n ;
+        }
+        return nodeMaxWidth ; 
+    }
+    
+    public static int calcWidthTriples(PrefixMap prefixMap, String baseURI, Collection<Triple> triples, int minWidth, int maxWidth)
+    {
+        Node prev = null ; 
+        int nodeMaxWidth = minWidth ;
+
+        for ( Triple triple : triples )
+        {
+            Node n = triple.getPredicate() ;
+            if ( prev != null && prev.equals(n) )
+                continue ;
+            int len = calcWidth(prefixMap, baseURI, n) ;
+            if ( len > maxWidth )
+                continue ;
+            if ( nodeMaxWidth < len )
+                nodeMaxWidth = len ;
+            prev = n ;
+        }
+        return nodeMaxWidth ;
+    }
+
+    
+    private static class IndentedWriterWriter extends IndentedWriter
+    {
+        IndentedWriterWriter(Writer w) { super(w) ; }
+    }
+
+    public static IndentedWriter create(Writer writer)  { return new IndentedWriterWriter(writer) ; }
+
+    public static PrefixMap prefixMap(Graph graph)      { return PrefixMapFactory.create(graph.getPrefixMapping()) ; }
+    
+    public static WriterGraphRIOTBase adapter(WriterDatasetRIOT writer)
+    { return new WriterAdapter(writer) ; }
+    
+    private static class WriterAdapter extends WriterGraphRIOTBase
+    {
+        private WriterDatasetRIOT writer ;
+
+        WriterAdapter(WriterDatasetRIOT writer) { this.writer = writer ; }
+        @Override
+        public Lang getLang()
+        { return writer.getLang() ; }
+
+        @Override
+        public void write(OutputStream out, Graph graph, PrefixMap prefixMap, String baseURI, Context context)
+        { writer.write(out, RiotWriterLib.dataset(graph), prefixMap, baseURI, context) ; }
+        
+        @Override
+        public void write(Writer out, Graph graph, PrefixMap prefixMap, String baseURI, Context context)
+        { writer.write(out, RiotWriterLib.dataset(graph), prefixMap, baseURI, context) ; }
+    }
+}
+

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NQuadsWriter.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NQuadsWriter.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NQuadsWriter.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NQuadsWriter.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,69 @@
+/*
+ * 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 org.apache.jena.riot.writer;
+
+import java.io.OutputStream ;
+import java.io.Writer ;
+import java.util.Iterator ;
+
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.StreamRDF ;
+import org.apache.jena.riot.system.StreamRDFLib ;
+
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+import com.hp.hpl.jena.sparql.util.Context ;
+
+public class NQuadsWriter extends WriterDatasetRIOTBase
+{
+    public static void write(OutputStream out, Iterator<Quad> iter)
+    {
+        StreamRDF s = new WriterStreamRDFTuples(out) ;
+        s.start() ;
+        StreamRDFLib.quadsToStream(s, iter) ;
+        s.finish();
+    }
+    
+    public static void write(Writer out, Iterator<Quad> iter)
+    {
+        StreamRDF s = new WriterStreamRDFTuples(out) ;
+        s.start() ;
+        StreamRDFLib.quadsToStream(s, iter) ;
+        s.finish();
+    }
+
+    @Override
+    public Lang getLang()
+    {
+        return Lang.NQUADS ;
+    }
+
+    @Override
+    public void write(Writer out, DatasetGraph dataset, PrefixMap prefixMap, String baseURI, Context context)
+    {
+        write(out, dataset.find(null, null, null, null)) ;
+    }
+
+    @Override
+    public void write(OutputStream out, DatasetGraph dataset, PrefixMap prefixMap, String baseURI, Context context)
+    {
+        write(out, dataset.find(null, null, null, null)) ;
+    }
+}

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NTriplesWriter.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NTriplesWriter.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NTriplesWriter.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NTriplesWriter.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,69 @@
+/*
+ * 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 org.apache.jena.riot.writer;
+
+import java.io.OutputStream ;
+import java.io.Writer ;
+import java.util.Iterator ;
+
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.StreamRDF ;
+import org.apache.jena.riot.system.StreamRDFLib ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.graph.Triple ;
+import com.hp.hpl.jena.sparql.util.Context ;
+
+public class NTriplesWriter extends WriterGraphRIOTBase
+{
+    public static void write(OutputStream out, Iterator<Triple> iter)
+    {
+        StreamRDF s = new WriterStreamRDFTuples(out) ;
+        s.start() ;
+        StreamRDFLib.triplesToStream(s, iter) ;
+        s.finish();
+    }
+    
+    public static void write(Writer out, Iterator<Triple> iter)
+    {
+        StreamRDF s = new WriterStreamRDFTuples(out) ;
+        s.start() ;
+        StreamRDFLib.triplesToStream(s, iter) ;
+        s.finish();
+    }
+
+    @Override
+    public Lang getLang()
+    {
+        return Lang.NTRIPLES ;
+    }
+
+    @Override
+    public void write(Writer out, Graph graph, PrefixMap prefixMap, String baseURI, Context context)
+    {
+        write(out, graph.find(null, null, null)) ;
+    }
+
+    @Override
+    public void write(OutputStream out, Graph graph, PrefixMap prefixMap, String baseURI, Context context)
+    {
+        write(out, graph.find(null, null, null)) ;
+    }
+}

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NullWriter.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NullWriter.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NullWriter.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/NullWriter.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,60 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import java.io.OutputStream ;
+import java.io.Writer ;
+
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.RDFFormat ;
+import org.apache.jena.riot.WriterDatasetRIOT ;
+import org.apache.jena.riot.WriterDatasetRIOTFactory ;
+import org.apache.jena.riot.system.PrefixMap ;
+
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.util.Context ;
+
+/** Null writer for datasets - can be used for RDF graphs via the adapter in from RiotWriterLib */ 
+public class NullWriter implements WriterDatasetRIOT
+{
+    public static WriterDatasetRIOTFactory factory = new WriterDatasetRIOTFactory() {
+        @Override
+        public WriterDatasetRIOT create(RDFFormat syntaxForm)
+        {
+            return new NullWriter(syntaxForm) ;
+        }} ;
+        
+    private RDFFormat format ;
+    
+    private NullWriter(RDFFormat format) { this.format = format ; }
+        
+    @Override
+    public Lang getLang()
+    {
+        return format.getLang() ;
+    }
+
+    @Override
+    public void write(OutputStream out, DatasetGraph datasetGraph, PrefixMap prefixMap, String baseURI, Context context)
+    {}
+
+    @Override
+    public void write(Writer out, DatasetGraph datasetGraph, PrefixMap prefixMap, String baseURI, Context context)
+    {}
+}

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFJSONWriter.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFJSONWriter.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFJSONWriter.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFJSONWriter.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,107 @@
+/*
+ * 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 org.apache.jena.riot.writer;
+
+import java.io.OutputStream ;
+import java.io.Writer ;
+import java.util.HashMap ;
+import java.util.HashSet ;
+import java.util.Map ;
+import java.util.Set ;
+
+import org.apache.jena.atlas.lib.Pair ;
+import org.apache.jena.atlas.lib.Sink ;
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.Prologue ;
+import org.apache.jena.riot.system.SyntaxLabels ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.graph.GraphUtil ;
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.Triple ;
+import com.hp.hpl.jena.sparql.util.Context ;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator ;
+
+public class RDFJSONWriter extends WriterGraphRIOTBase
+{
+    public RDFJSONWriter() {}
+    
+	public static void output(OutputStream out, Graph graph) {
+        Prologue prologue = Prologue.create(null, null) ; // (null, graph.getPrefixMapping()) ;
+		Sink<Pair<Node, Map<Node, Set<Node>>>> sink = new SinkEntityOutput(out, prologue, SyntaxLabels.createNodeToLabel()) ;
+		output( sink, graph ) ;
+	}
+	
+	public static void output(Writer out, Graph graph) {
+        Prologue prologue = Prologue.create(null, null) ; // (null, graph.getPrefixMapping()) ;
+		Sink<Pair<Node, Map<Node, Set<Node>>>> sink = new SinkEntityOutput(out, prologue, SyntaxLabels.createNodeToLabel()) ;
+		output( sink, graph ) ;
+	}
+
+	private static void output(Sink<Pair<Node, Map<Node, Set<Node>>>> sink, Graph graph) {
+		ExtendedIterator<Node> subjects = GraphUtil.listSubjects(graph, Node.ANY, Node.ANY) ;
+		try {
+			Map<Node, Set<Node>> predicates = new HashMap<Node, Set<Node>>() ;
+			while ( subjects.hasNext() ) {
+				Node subject = subjects.next() ;
+				ExtendedIterator<Triple> triples = graph.find(subject, Node.ANY, Node.ANY) ;
+				try {
+					while ( triples.hasNext() ) {
+						Triple triple = triples.next() ;
+						Node p = triple.getPredicate() ;
+						if ( predicates.containsKey(p) ) {
+							predicates.get(p).add(triple.getObject()) ; 
+						} else {
+							Set<Node> objects = new HashSet<Node>() ;
+							objects.add(triple.getObject()) ;
+							predicates.put(p, objects) ;
+						}
+					}				
+				} finally {
+					if ( triples != null ) triples.close() ;
+				}
+				sink.send(new Pair<Node, Map<Node, Set<Node>>>(subject, predicates)) ;
+				predicates.clear() ;
+			}			
+		} finally {
+			if ( subjects != null ) subjects.close() ;
+			sink.close() ;
+		}
+	}
+
+    @Override
+    public Lang getLang()
+    {
+        return Lang.RDFJSON ;
+    }
+
+    @Override
+    public void write(Writer out, Graph graph, PrefixMap prefixMap, String baseURI, Context context)
+    {
+        output(out, graph) ;
+    }
+
+    @Override
+    public void write(OutputStream out, Graph graph, PrefixMap prefixMap, String baseURI, Context context)
+    {
+        output(out, graph) ;
+    }
+	
+}

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFXMLAbbrevWriter.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFXMLAbbrevWriter.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFXMLAbbrevWriter.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFXMLAbbrevWriter.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,43 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.adapters.AdapterRDFWriter ;
+
+import com.hp.hpl.jena.rdf.model.RDFWriter ;
+import com.hp.hpl.jena.xmloutput.impl.Abbreviated ;
+
+/** Wrapper to the RDF/XML writer (preRIOT). */
+
+public class RDFXMLAbbrevWriter extends AdapterRDFWriter
+{
+    
+    public RDFXMLAbbrevWriter() {} 
+    
+    @Override
+    protected RDFWriter create() { return new Abbreviated() ; }
+    
+    @Override
+    public Lang getLang()
+    {
+        return Lang.RDFXML ;
+    }
+}
+

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFXMLPlainWriter.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFXMLPlainWriter.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFXMLPlainWriter.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/RDFXMLPlainWriter.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,41 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.adapters.AdapterRDFWriter ;
+
+import com.hp.hpl.jena.rdf.model.RDFWriter ;
+import com.hp.hpl.jena.xmloutput.impl.Basic ;
+
+/** Wrapper to the RDF/XML writer (preRIOT). */
+
+public class RDFXMLPlainWriter extends AdapterRDFWriter
+{
+    public RDFXMLPlainWriter() {}
+    
+    @Override
+    protected RDFWriter create() { return new Basic() ; }
+    
+    @Override
+    public Lang getLang()
+    {
+        return Lang.RDFXML ;
+    }
+}

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/SinkEntityOutput.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/SinkEntityOutput.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/SinkEntityOutput.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/SinkEntityOutput.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,148 @@
+/*
+ * 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 org.apache.jena.riot.writer;
+
+import java.io.OutputStream ;
+import java.io.Writer ;
+import java.util.Map ;
+import java.util.Set ;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.json.io.JSWriter ;
+import org.apache.jena.atlas.lib.Pair ;
+import org.apache.jena.atlas.lib.Sink ;
+import org.apache.jena.riot.RiotException ;
+import org.apache.jena.riot.out.NodeToLabel ;
+import org.apache.jena.riot.system.Prologue ;
+import org.apache.jena.riot.system.SyntaxLabels ;
+
+import com.hp.hpl.jena.graph.Node ;
+
+public class SinkEntityOutput implements Sink<Pair<Node, Map<Node, Set<Node>>>> {
+
+    private Prologue prologue = null ;
+    private NodeToLabel labelPolicy = null ;
+    private JSWriter out ;
+	
+    public SinkEntityOutput(OutputStream outs)
+    {
+        this(outs, null, SyntaxLabels.createNodeToLabel()) ;
+    }
+    
+    public SinkEntityOutput(OutputStream outs, Prologue prologue, NodeToLabel labels)
+    {
+    	init(new JSWriter(outs), prologue, labels) ;
+    }
+
+    public SinkEntityOutput(Writer outs)
+    {
+        this(outs, null, SyntaxLabels.createNodeToLabel()) ;
+    }
+    
+    public SinkEntityOutput(Writer outs, Prologue prologue, NodeToLabel labels)
+    {
+    	init(new JSWriter(new IndentedWriterEx(outs)), prologue, labels) ;
+    }
+    
+    private void init (JSWriter out, Prologue prologue, NodeToLabel labels) 
+    {
+    	this.out = out ;
+    	setPrologue(prologue) ;
+    	setLabelPolicy(labels) ;
+    	out.startOutput() ;
+    	out.startObject() ;
+    }
+
+    public void setPrologue(Prologue prologue)
+    {
+    	this.prologue = prologue ;
+    }
+
+    public void setLabelPolicy(NodeToLabel labels)
+    {
+    	this.labelPolicy = labels ;
+    }
+
+    @Override
+	public void send(Pair<Node, Map<Node, Set<Node>>> item) {
+		Node s = item.getLeft() ;
+		if ( s.isBlank() ) {
+			out.key("_:" + s.getBlankNodeLabel()) ;
+		} else if ( s.isURI() ) {
+			out.key(s.getURI()) ;
+		} else {
+			throw new RiotException ("Only URIs or blank nodes are legal subjects.") ;
+		}
+		out.startObject() ;
+		// out.pair(key, value) ;
+		Map<Node, Set<Node>> predicates = item.getRight() ;
+		for (Node p : predicates.keySet() ) {
+			out.key(p.getURI()) ;
+			out.startArray() ;
+			Set<Node> objects = predicates.get(p) ;
+			int i = 0;
+			for ( Node o : objects ) {
+				out.startObject() ;
+				if ( o.isBlank() ) {
+					out.pair("type", "bnode") ;
+					out.pair("value", "_:" + o.getBlankNodeLabel()) ;
+				} else if ( o.isURI() ) {
+					out.pair("type", "uri") ;
+					out.pair("value", o.getURI()) ;					
+				} else if ( o.isLiteral() ) {
+			        String dt = o.getLiteralDatatypeURI() ;
+			        String lang = o.getLiteralLanguage() ;
+			        String lex = o.getLiteralLexicalForm() ;
+					out.pair("type", "literal") ;
+					out.pair("value", lex) ;
+			        if ( dt != null ) 
+			        	out.pair("datatype", dt) ;
+			        if ( ( lang != null ) && ( lang != "" ) ) 
+			        	out.pair("lang", lang) ;
+				}
+				out.finishObject() ;
+				if (i < objects.size() - 1)
+				{
+					out.arraySep();
+				}
+				i++;
+			}
+			out.finishArray() ;
+		}
+		out.finishObject() ;
+	}
+
+    @Override
+	public void flush() {
+		out.finishObject() ;
+		out.finishOutput();
+	}
+	
+    @Override
+	public void close() {
+		flush() ;
+	}
+
+    private class IndentedWriterEx extends IndentedWriter {
+		public IndentedWriterEx(Writer writer) {
+			super(writer);
+		}
+    }
+
+}

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriter.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriter.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriter.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriter.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,98 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import static org.apache.jena.riot.writer.WriterConst.* ;
+
+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 ;
+
+/** TriG pretty writer */
+public class TriGWriter extends TriGWriterBase
+{
+    @Override
+    protected void output$(IndentedWriter iOut, DatasetGraph dsg, PrefixMap prefixMap, String baseURI)
+    {
+        TriGWriter$ w = new TriGWriter$(iOut, prefixMap, baseURI) ;
+        w.write(dsg) ;
+    }
+
+    private static class TriGWriter$ extends TurtleShell
+    {
+        TriGWriter$(IndentedWriter out, PrefixMap prefixMap, String baseURI)
+        {   
+            super(out, prefixMap, baseURI) ;
+        }
+
+        private void write(DatasetGraph dsg)
+        {
+            writeBase(baseURI) ;
+            writePrefixes(prefixMap) ;
+            if ( ! prefixMap.isEmpty() && !dsg.isEmpty() )
+                out.println() ;
+
+            Iterator<Node> graphNames = dsg.listGraphNodes() ;
+
+            writeGraph(null, dsg.getDefaultGraph()) ;
+
+            for ( ; graphNames.hasNext() ; )
+            {
+                out.println() ;
+                Node gn = graphNames.next() ;
+                writeGraph(gn, dsg.getGraph(gn)) ;
+            }
+        }
+
+        private void writeGraph(Node name, Graph graph)
+        {
+            boolean dftGraph =  ( name == null || name == Quad.defaultGraphNodeGenerated  ) ;
+            boolean NL_START =  ( dftGraph ? NL_GDFT_START : NL_GNMD_START ) ; 
+            boolean NL_END =    ( dftGraph ? NL_GDFT_END : NL_GNMD_END ) ; 
+            int INDENT_GRAPH =  ( dftGraph ? INDENT_GDFT : INDENT_GNMD ) ; 
+            
+            if ( ! dftGraph )
+            {
+                writeNode(name) ;
+                out.print(" ") ;
+            }
+            out.print("{") ;
+            if ( NL_START )
+                out.println() ;
+            else 
+                out.print(" ") ;
+            
+            out.incIndent(INDENT_GRAPH) ;
+            // Pretty Turtle Writer. 
+            writeGraphTTL(graph) ;
+            out.decIndent(INDENT_GRAPH) ;
+            
+            if ( NL_END )
+                out.ensureStartOfLine() ;
+            out.println("}") ;
+        }
+    }
+}
+

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterBase.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterBase.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterBase.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterBase.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,59 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import java.io.OutputStream ;
+import java.io.Writer ;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.RiotWriterLib ;
+
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.util.Context ;
+
+/** TriG writer base class - ways to invoke a TriG writer */
+public abstract class TriGWriterBase extends WriterDatasetRIOTBase
+{
+    @Override
+    public Lang getLang()
+    {
+        return Lang.TRIG ;
+    }
+
+    @Override
+    public void write(Writer out, DatasetGraph dsg, PrefixMap prefixMap, String baseURI, Context context)
+    {
+        IndentedWriter iOut = RiotWriterLib.create(out) ;
+        output$(iOut, dsg, prefixMap, baseURI) ;
+        iOut.flush() ;
+    }
+
+    @Override
+    public void write(OutputStream out, DatasetGraph dsg, PrefixMap prefixMap, String baseURI, Context context)
+    {
+        IndentedWriter iOut = new IndentedWriter(out) ;
+        output$(iOut, dsg, prefixMap, baseURI) ;
+        iOut.flush() ;
+    }
+    
+    protected abstract void output$(IndentedWriter iOut, DatasetGraph dsg, PrefixMap prefixMap, String baseURI) ;
+}
+

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterBlocks.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterBlocks.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterBlocks.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterBlocks.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,39 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.StreamRDF ;
+
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+
+/** TriG writer that streams - print in blocks of quads clustered
+ *  by adjacent same graph and same subject
+ */
+public class TriGWriterBlocks extends TriGWriterBase
+{
+    @Override
+    protected void output$(IndentedWriter iOut, DatasetGraph dsg, PrefixMap prefixMap, String baseURI)
+    {
+        StreamRDF dest = new WriterStreamRDFBlocks(iOut) ;
+        WriterStream.write(dest, dsg, prefixMap, baseURI) ;
+    }
+}
+

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterFlat.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterFlat.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterFlat.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TriGWriterFlat.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,39 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.StreamRDF ;
+
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+
+/** TriG writer that writes quads one per line
+ *  in TriG form with prefixes and short form literals (e.g. integers) 
+ */
+
+public class TriGWriterFlat extends TriGWriterBase
+{
+    @Override
+    protected void output$(IndentedWriter iOut, DatasetGraph datasetGraph, PrefixMap prefixMap, String baseURI)
+    {
+        StreamRDF dest = new WriterStreamRDFFlat(iOut) ;
+        WriterStream.write(dest, datasetGraph, prefixMap, baseURI) ;
+    }
+}

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleShell.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleShell.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleShell.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleShell.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,680 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for ad
+ * ditional 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 org.apache.jena.riot.writer;
+
+import static org.apache.jena.riot.system.RiotWriterLib.* ;
+import static org.apache.jena.riot.writer.WriterConst.* ;
+
+import java.util.* ;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.lib.Pair ;
+import org.apache.jena.riot.other.GLib ;
+import org.apache.jena.riot.out.NodeFormatter ;
+import org.apache.jena.riot.out.NodeFormatterTTL ;
+import org.apache.jena.riot.out.NodeToLabel ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.PrefixMapFactory ;
+import org.apache.jena.riot.system.RiotWriterLib ;
+
+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.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 (Turle, 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)
+    {
+        this.out = out ;
+        if ( pmap == null )
+            pmap = PrefixMapFactory.emptyPrefixMap() ;
+        this.nodeFmt = new NodeFormatterTTL(baseURI,  pmap, NodeToLabel.createScopeByDocument()) ;
+        this.prefixMap = pmap ;
+        this.baseURI = baseURI ;
+    }
+
+    protected void writeBase(String base)
+    {
+        RiotWriterLib.writeBase(out, base) ;
+    }
+
+    protected void writePrefixes(PrefixMap prefixMap)
+    {
+        RiotWriterLib.writePrefixes(out, prefixMap) ;
+    }
+
+    protected void writeGraphTTL(Graph graph)
+    {
+        ShellGraph x = new ShellGraph(graph) ;
+        x.writeGraph() ;
+    }
+    
+    // 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<Node>()  ;
+            this.freeBnodes     = new HashSet<Node>()  ;
+            
+            this.lists          = new HashMap<Node, List<Node>>() ;
+            this.freeLists      = new HashMap<Node, List<Node>>() ;
+            this.nLinkedLists   = new HashMap<Node, List<Node>>() ;
+            this.listElts       = new HashSet<Node>() ;
+
+            // Must be in this order.
+            findLists() ;
+            findBNodesSyntax() ;
+            // 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<Node>() ;           // Nodes known not to meet the requirement.
+
+            ExtendedIterator<Triple> iter = graph.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))
+                    {
+                        // And not a list ...
+                        int sConn = inLinks(subj) ;
+                        if ( sConn == 0 )
+                            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 )
+                        nestedObjects.add(obj) ;
+                    // else connected multiple times.
+                }
+            } 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)  
+         */
+        private void findLists()
+        {
+            List<Triple> tails = RiotWriterLib.triples(graph, Node.ANY, RDF_Rest, RDF_Nil) ;
+            for ( Triple t : tails )
+            {
+                // Returns the elements, reversed.
+                Collection<Node> listElts2 = new HashSet<Node>() ;
+                Pair<Node, List<Node>> p = followTailToHead(t.getSubject(), listElts2) ;
+                if ( p != null )
+                {
+                    Node headElt = p.getLeft() ; 
+                    // Free standing?private
+                    List<Node> elts = p.getRight() ;
+                    long numLinks = RiotWriterLib.countTriples(graph, null, null, headElt) ;
+                    if ( numLinks == 1 )
+                        lists.put(headElt, elts) ;
+                    else if ( numLinks == 0 )
+                        // 0 connected lists
+                        freeLists.put(headElt, elts) ;
+                    else 
+                        // Two triples to this list.
+                        nLinkedLists.put(headElt, elts) ;
+                    listElts.addAll(listElts2) ;
+                }
+            }
+        }
+
+        // return head elt node, list of elements.
+        private Pair<Node, List<Node>> followTailToHead(Node lastListElt, Collection<Node> listElts)
+        {
+            List<Node> listCells = new ArrayList<Node>() ;
+            List<Node> eltsReversed = new ArrayList<Node>() ;
+            List<Triple> acc =  new ArrayList<Triple>() ;
+            Node x = lastListElt ;
+
+            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) ;
+                    break ;
+                }
+
+                Triple t = RiotWriterLib.triple1(graph, 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 = RiotWriterLib.triples(graph, null, null, x) ;
+                long numRest = RiotWriterLib.countTriples(graph, null, RDF_Rest, x) ;
+                if ( numRest != 1 )
+                {
+                    // Head of well-formed list.
+                    // Classified by 0,1,more links later.
+                    listCells.add(x) ;
+                    break ;
+                }
+                // numRest == 1
+                int numLinks = acc2.size() ;
+                if ( numLinks > 1 )
+                    // Non-list links to x
+                    break ;
+                // Valid.
+                Triple tLink = acc2.get(0) ;
+                x = tLink.getSubject() ;
+            }
+            // Success.
+            listElts.addAll(listCells) ;
+            Collections.reverse(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 = RiotWriterLib.triple1(graph, x, RDF_Rest, null) ; // Which we came up to get here :-(
+            if ( t1 == null )
+                return false ;
+            Triple t2 = RiotWriterLib.triple1(graph, x, RDF_First, null) ;
+            if ( t2 == null )
+                return false ;
+            long N = RiotWriterLib.countTriples(graph, x, null, null) ;
+            if ( N != 2 )
+                return false ;
+            acc.add(t1) ;
+            acc.add(t2) ;
+            return true ;
+        }
+
+        // ----
+
+        private void writeGraph()
+        {
+            Iterator<Node> subjects = GLib.listSubjects(graph) ;
+            boolean somethingWritten = writeBySubject(subjects) ;
+
+            // Write remainders
+            // 1 - Shared lists
+            // 2 - Free standing lists
+            
+            if ( ! nLinkedLists.isEmpty() )
+                somethingWritten = writeNLinkedLists(somethingWritten) ;
+            
+            if ( ! freeLists.isEmpty() )
+                somethingWritten = writeFreeLists(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
+            // the remainer as a pretty list
+            for ( Node n : nLinkedLists.keySet() )
+            {
+                if ( somethingWritten ) out.println() ;
+                somethingWritten = true ;
+
+                List<Node> x = nLinkedLists.get(n) ;
+                writeNode(n) ;
+
+                if ( out.getCol() > LONG_SUBJECT )
+                    println() ;
+                else
+                    gap(GAP_S_P) ;
+                out.incIndent(INDENT_PREDICATE) ;
+                // ----
+                // DRY writeCluster.
+                out.pad() ;
+                writeNode(RDF_First) ;
+                print(" ") ;
+                writeNode(x.get(0)) ;
+                print(" ;") ;
+                println() ;
+                writeNode(RDF_Rest) ;
+                print("  ") ;
+                x = x.subList(1, x.size()) ;
+                list(x) ;
+                print(" .") ;
+                out.decIndent(INDENT_PREDICATE) ;
+                println() ;
+            }
+            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 lists.
+            for ( Node n : freeLists.keySet() )
+            {
+                if ( somethingWritten )
+                    out.println() ;
+                somethingWritten = true ;
+
+                List<Node> x = freeLists.get(n) ;
+                // Print first element for the [ ... ]
+                out.print("[ ") ;
+
+                writeNode(RDF_First) ;
+                print(" ") ;
+                writeNode(x.get(0)) ;
+                print(" ; ") ;
+                writeNode(RDF_Rest) ;
+                print(" ") ;
+                x = x.subList(1, x.size()) ;
+                // Print remainder.
+                list(x) ;
+                out.println(" ] .") ;
+            }
+            return somethingWritten ;
+        }
+
+        // return true if did write something.
+        private boolean writeBySubject(Iterator<Node> subjects)
+        {
+            boolean first = true ;
+            for ( ; subjects.hasNext() ; )
+            {
+                Node subj = subjects.next() ;
+                if ( nestedObjects.contains(subj) )
+                    continue ;
+                
+                if ( listElts.contains(subj) )
+                    continue ;
+                if ( ! first ) 
+                    out.println() ;
+                first = false ;
+                if ( freeBnodes.contains(subj) ) 
+                {
+                    // Write in "[....]" form.
+                    nestedObject(subj) ;
+                    out.println(" .") ;
+                    continue ;
+                }
+
+                Collection<Triple> cluster = RiotWriterLib.triplesOfSubject(graph, 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 ;
+            writeNode(subject) ;
+
+            if ( out.getCol() > LONG_SUBJECT )
+                out.println() ; 
+            else
+                gap(GAP_S_P) ;
+            out.incIndent(INDENT_PREDICATE) ;
+            out.pad() ;
+            writePredicateObjectList(cluster) ;
+            out.decIndent(INDENT_PREDICATE) ;
+            // End of cluster.
+            print(" .") ;
+            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)
+        {
+            Map<Node, List<Node>> pGroups = groupByPredicates(cluster) ;
+            Collection<Node> predicates = pGroups.keySet() ;
+            
+            // Find longest predicate URI
+            int predicateMaxWidth = calcWidth(prefixMap, baseURI, predicates, MIN_PREDICATE, LONG_PREDICATE) ;
+
+            boolean first = true ;
+
+            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<Node>() ;        // Literals in the group 
+                List<Node> rdfSimpleNodes = new ArrayList<Node>() ;     // Non-literals, printed 
+                List<Node> rdfComplexNodes = new ArrayList<Node>() ;    // 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 )
+                {
+                    writePredicateObjectList(p, rdfLiterals, predicateMaxWidth, first) ;
+                    first = false ;
+                }
+                if ( rdfSimpleNodes.size() != 0 )
+                {
+                    writePredicateObjectList(p, rdfSimpleNodes, predicateMaxWidth, first) ;
+                    first = false ;
+                }
+                
+                for ( Node o : rdfComplexNodes )
+                {
+                    writePredicateObject(p, o, predicateMaxWidth, first) ;
+                    first = false ;
+                }
+            }
+        }
+        
+        private void writePredicateObject(Node p, Node obj, int predicateMaxWidth, boolean first)
+        {
+            writePredicate(p, predicateMaxWidth, first) ;
+            out.incIndent(INDENT_OBJECT) ;  
+            writeNodePretty(obj) ;
+            out.decIndent(INDENT_OBJECT) ;
+        }
+
+        private void writePredicateObjectList(Node p, List<Node> objects, int predicateMaxWidth, boolean first)
+        {
+            writePredicate(p, predicateMaxWidth, first) ;
+            out.incIndent(INDENT_OBJECT) ;  
+            boolean firstObject = true ;
+            for ( Node o : objects) 
+            {
+                if ( ! firstObject )
+                    out.print(" , ") ;
+                else
+                    firstObject = false ; 
+                writeNode(o) ;
+                //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)
+        {
+            if ( first )
+                first = false ;
+            else
+            {
+                print(" ;") ;
+                println() ;
+            }
+            int colPredicateStart = out.getAbsoluteIndent() ;
+            
+            if ( ! prefixMap.contains(rdfNS) && RDF_type.equals(p) )
+                print("a") ;
+            else
+                writeNode(p) ;
+            int colPredicateFinish = out.getCol() ;
+            int wPredicate = (colPredicateFinish-colPredicateStart) ;
+
+            if ( wPredicate > LONG_PREDICATE )
+                println() ;
+            else
+            {
+                out.pad(predicateMaxWidth) ;
+                //out.print(' ', predicateMaxWidth-wPredicate) ;
+                gap(GAP_P_O) ;
+            }
+        }
+            
+        private Map<Node, List<Node>> groupByPredicates(Collection<Triple> cluster)
+        {
+            SortedMap<Node, List<Node>> x = new TreeMap<Node, List<Node>>(compPredicates) ; 
+            for ( Triple t : cluster )
+            {
+                Node p = t.getPredicate() ;
+                if ( ! x.containsKey(p) )
+                    x.put(p, new ArrayList<Node>()) ;
+                x.get(p).add(t.getObject()) ;
+            }
+            
+            return x ;
+        }
+
+        private int countPredicates(Collection<Triple> cluster)
+        {
+            Set<Node> x = new HashSet<Node>() ; 
+            for ( Triple t : cluster )
+            {
+                Node p = t.getPredicate() ;
+                x.add(p) ;
+            }
+            return x.size() ;
+        }
+
+        private void nestedObject(Node node)
+        {
+            Collection<Triple> x = RiotWriterLib.triplesOfSubject(graph, node) ;
+
+            if ( x.isEmpty() )
+            {
+                print("[] ") ;
+                return ;
+            }
+
+            int pCount = countPredicates(x) ;
+            
+            if ( pCount == 1 )
+            {
+                print("[ ") ;
+                out.incIndent(2) ;
+                writePredicateObjectList(x) ;
+                out.decIndent(2) ;
+                print(" ]") ;
+                return ;
+            }
+
+            // Two or more.
+            int indent0 = out.getAbsoluteIndent() ;
+            int here = out.getCol() ;
+            out.setAbsoluteIndent(here) ;
+            print("[ ") ;
+            out.incIndent(2) ;
+            writePredicateObjectList(x) ;
+            out.decIndent(2) ;
+            if ( true )
+            {
+                println() ; // Newline for "]"
+                print("]") ;
+            }
+            else
+            {   // Compact
+                print(" ]") ;
+            }
+            out.setAbsoluteIndent(indent0) ;
+        }
+        
+        // Write a list
+        private void list(List<Node> elts)
+        {
+            if ( elts.size() == 0 )
+            {
+                out.print("()") ;
+                return ;
+            }
+            
+            out.print("(") ;
+            for ( Node n : elts )
+            {
+                out.print(" ") ;
+                writeNodePretty(n) ;
+            }
+
+            out.print(" )") ;
+        }
+        
+        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 ;
+            return false ;
+        }
+        
+        // --> write S or O??
+        private void writeNodePretty(Node obj)
+        {
+            // Order matters? - one connected objects may include list elements.
+            if ( lists.containsKey(obj) )
+                list(lists.get(obj)) ; 
+            else if ( nestedObjects.contains(obj) )
+                nestedObject(obj) ;
+            else if ( RDF_Nil.equals(obj) )
+                out.println("()") ;
+            else
+                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)
+        {
+            if ( p.equals(RDF_type) )
+                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 )
+            {
+                // Java 1.7
+                //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) ; 
+        }
+    }
+
+    private static Comparator<Node> compPredicates = new ComparePredicates() ;
+    
+    protected final void writeNode(Node node)
+    {
+        nodeFmt.format(out, node) ;
+    }
+
+    private void print(String x)
+    {
+        out.print(x) ;
+    }
+
+    private void gap(int gap)
+    {
+        out.print(' ', gap) ;
+    }
+
+    // flush aggressively (debugging)
+    private void println()
+    {
+        out.println() ;
+        //out.flush() ;
+    }
+}
+

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriter.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriter.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriter.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriter.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,51 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.riot.system.PrefixMap ;
+
+import com.hp.hpl.jena.graph.Graph ;
+
+public class TurtleWriter extends TurtleWriterBase
+{
+    @Override
+    protected void output$(IndentedWriter iOut, Graph graph, PrefixMap prefixMap, String baseURI)
+    {
+          TurtleWriter$ w = new TurtleWriter$(iOut, prefixMap, baseURI) ;
+          w.write(graph) ;
+    }
+
+    private static class TurtleWriter$ extends TurtleShell
+    {
+        public TurtleWriter$(IndentedWriter out, PrefixMap prefixMap, String baseURI)
+        {
+            super(out, prefixMap, baseURI) ;
+        }
+        private void write(Graph graph)
+        {
+            writeBase(baseURI) ;
+            writePrefixes(prefixMap) ;
+            if ( ! prefixMap.isEmpty() && !graph.isEmpty() )
+                out.println() ;
+            writeGraphTTL(graph) ;
+        }
+    }
+}
+

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterBase.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterBase.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterBase.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterBase.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,57 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import java.io.OutputStream ;
+import java.io.Writer ;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.RiotWriterLib ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.sparql.util.Context ;
+
+public abstract class TurtleWriterBase extends WriterGraphRIOTBase
+{
+    @Override
+    public Lang getLang()
+    {
+        return Lang.TURTLE ;
+    }
+
+    @Override
+    public void write(Writer out, Graph graph, PrefixMap prefixMap, String baseURI, Context context)
+    {
+        IndentedWriter iOut = RiotWriterLib.create(out) ;
+        output$(iOut, graph, prefixMap, baseURI) ;
+        iOut.flush() ;
+    }
+
+    @Override
+    public void write(OutputStream out, Graph graph, PrefixMap prefixMap, String baseURI, Context context)
+    {
+        IndentedWriter iOut = new IndentedWriter(out) ;
+        output$(iOut, graph, prefixMap, baseURI) ;
+        iOut.flush() ;
+    }
+    
+    protected abstract void output$(IndentedWriter iOut, Graph graph, PrefixMap prefixMap, String baseURI) ;
+}

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterBlocks.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterBlocks.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterBlocks.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterBlocks.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,39 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.StreamRDF ;
+
+import com.hp.hpl.jena.graph.Graph ;
+
+/** Turtle writer that streams - print in blocks of triples formatted
+ *  by adjacent same subject.
+ */
+public class TurtleWriterBlocks extends TurtleWriterBase
+{
+    @Override
+    protected void output$(IndentedWriter out, Graph graph, PrefixMap prefixMap, String baseURI)
+    {
+        StreamRDF dest = new WriterStreamRDFBlocks(out) ;
+        WriterStream.write(dest, graph, prefixMap, baseURI) ;
+    }
+}
+

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterFlat.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterFlat.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterFlat.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/TurtleWriterFlat.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,36 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.StreamRDF ;
+
+import com.hp.hpl.jena.graph.Graph ;
+
+/** Write Turtle with omne triple on one line with prefixed names, with short form literals (e.g. integers) */   
+public class TurtleWriterFlat extends TurtleWriterBase
+{
+    @Override
+    protected void output$(IndentedWriter out, Graph graph, PrefixMap prefixMap, String baseURI)
+    {
+        StreamRDF dest = new WriterStreamRDFFlat(out) ;
+        WriterStream.write(dest, graph, prefixMap, baseURI) ;
+    }
+}
\ No newline at end of file

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterConst.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterConst.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterConst.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterConst.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,88 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.vocabulary.RDF ;
+
+public class WriterConst
+{
+    // See INDENT_PREDICATE
+//    public static final int MIN_SUBJECT     = 4 ;
+    
+    /** Minimum width of the predicate columns. */
+    public static final int MIN_PREDICATE   = 4 ;
+
+    /** Subjects longer than this have a NL after them. */ 
+    public static final int LONG_SUBJECT    = 20 ;
+    /** Predicates longer than this have a NL after them. */
+    public static final int LONG_PREDICATE  = 30 ;
+    
+    /** The IRI column in a prefix. */
+    public static final int PREFIX_IRI      = 15;
+    
+    // Pretty writers - do object lists?
+    // The block writers do not do object lists. 
+    public static boolean OBJECT_LISTS      = true ;
+    
+//    // Fixed column widths (unused).
+//    public static int COLW_SUBJECT          = 6 ;
+//    public static int COLW_PREDICATE        = 10 ;
+    
+    /** Column for start of predicate */  
+    public static final int INDENT_PREDICATE = 8 ;
+    
+    /** Column for start of object */
+    public static final int INDENT_OBJECT   = 8 ;
+
+    /** Indent for triples in default graph blocks */
+    public static final int INDENT_GDFT          = 2 ;
+    /** Indent for trinples in named graph blocks */
+    public static final int INDENT_GNMD          = 4 ;
+
+    
+    /** Minimum gap from S to P and from P to O */
+    public static final int MIN_GAP         = 2 ;
+
+    /** Minimum gap from S to P */
+    public static final int GAP_S_P         = MIN_GAP ;         
+    /** Minimum gap from P to O */
+    public static final int GAP_P_O         = MIN_GAP ;  
+    
+    /** Whether to put in a newline after the opening { of a default graph block */   
+    public static final boolean NL_GDFT_START    =  false ;
+    /** Whether to put in a newline after the opening { of a named graph block */   
+    public static final boolean NL_GNMD_START    =  true ;
+    
+    /** Whether to put the closing } of a default graph block on a newline */
+    public static final boolean NL_GDFT_END      =  true ;
+    /** Whether to put the closing } of a named graph block on a newline */
+    public static final boolean NL_GNMD_END      =  true ;
+
+    
+    // Constants.
+    public static final String rdfNS        = RDF.getURI() ;
+    public static final Node RDF_type       = RDF.Nodes.type ;
+    public static final Node RDF_First      = RDF.Nodes.first ;
+    public static final Node RDF_Rest       = RDF.Nodes.rest ;
+    public static final Node RDF_Nil        = RDF.Nodes.nil ;
+    
+
+}
+

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterDatasetRIOTBase.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterDatasetRIOTBase.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterDatasetRIOTBase.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterDatasetRIOTBase.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,43 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import java.io.OutputStream ;
+import java.io.Writer ;
+
+import org.apache.jena.riot.WriterDatasetRIOT ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.PrefixMapFactory ;
+
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.util.Context ;
+
+public abstract class WriterDatasetRIOTBase implements WriterDatasetRIOT
+{
+    private static PrefixMap prefixMap(DatasetGraph dataset)
+    {
+        return PrefixMapFactory.create(dataset.getDefaultGraph().getPrefixMapping()) ;
+    }
+    
+    @Override
+    public abstract void write(Writer out, DatasetGraph dataset, PrefixMap prefixMap, String baseURI, Context context) ;
+    
+    @Override
+    public abstract void write(OutputStream out, DatasetGraph dataset, PrefixMap prefixMap, String baseURI, Context context) ;
+}

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterGraphRIOTBase.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterGraphRIOTBase.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterGraphRIOTBase.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterGraphRIOTBase.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,37 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import java.io.OutputStream ;
+import java.io.Writer ;
+
+import org.apache.jena.riot.WriterGraphRIOT ;
+import org.apache.jena.riot.system.PrefixMap ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.sparql.util.Context ;
+
+public abstract class WriterGraphRIOTBase implements WriterGraphRIOT
+{
+    @Override
+    public abstract void write(Writer out, Graph graph, PrefixMap prefixMap, String baseURI, Context context) ;
+    
+    @Override
+    public abstract void write(OutputStream out, Graph graph, PrefixMap prefixMap, String baseURI, Context context) ;
+}

Added: jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterStream.java
URL: http://svn.apache.org/viewvc/jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterStream.java?rev=1452591&view=auto
==============================================================================
--- jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterStream.java (added)
+++ jena/branches/arq-riot-output/src/main/java/org/apache/jena/riot/writer/WriterStream.java Mon Mar  4 23:22:53 2013
@@ -0,0 +1,72 @@
+/**
+ * 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 org.apache.jena.riot.writer;
+
+import java.util.Iterator ;
+import java.util.Map.Entry ;
+
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.StreamRDF ;
+import org.apache.jena.riot.system.StreamRDFLib ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.graph.Triple ;
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+
+public class WriterStream
+{
+    private WriterStream() {}
+    
+    protected static void finish(StreamRDF dest)
+    { dest.finish() ; }
+
+    protected static void start(StreamRDF dest)
+    { dest.start() ; }
+
+    protected static void writePrefixes(StreamRDF dest, PrefixMap prefixMap)
+    {
+        if ( prefixMap != null )
+        {
+            for ( Entry<String, String> e : prefixMap.getMappingCopyStr().entrySet())
+                dest.prefix(e.getKey(), e.getValue()) ;
+        }
+    }
+
+    protected static void write(StreamRDF dest, DatasetGraph datasetGraph, PrefixMap prefixes, String baseURI) 
+    {
+        start(dest) ;
+        dest.base(baseURI) ;
+        writePrefixes(dest, prefixes) ;
+        Iterator<Quad> iter = datasetGraph.find(null, null, null, null) ;
+        StreamRDFLib.quadsToStream(dest, iter) ;
+        finish(dest) ;
+    }
+
+    protected static void write(StreamRDF dest, Graph graph, PrefixMap prefixes, String baseURI) 
+    {
+        start(dest) ;
+        dest.base(baseURI) ;
+        writePrefixes(dest, prefixes) ;
+        Iterator<Triple> iter = graph.find(null, null, null) ;
+        StreamRDFLib.triplesToStream(dest, iter) ;
+        finish(dest) ;
+    }
+}
+