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/01/31 21:20:50 UTC

svn commit: r1441178 [1/2] - in /jena/Experimental/riot-output: ./ src/ src/main/ src/main/java/ src/main/java/dev/ src/main/java/riot/ src/main/java/riot/other/ src/main/java/riot/out/ src/main/java/riot/writer/ src/main/resources/ src/test/ src/test/...

Author: andy
Date: Thu Jan 31 20:20:49 2013
New Revision: 1441178

URL: http://svn.apache.org/viewvc?rev=1441178&view=rev
Log:
Import to ASF

Added:
    jena/Experimental/riot-output/.classpath
    jena/Experimental/riot-output/.project
    jena/Experimental/riot-output/D.trig
    jena/Experimental/riot-output/D.ttl
    jena/Experimental/riot-output/README.md
    jena/Experimental/riot-output/W.trig
    jena/Experimental/riot-output/W.ttl
    jena/Experimental/riot-output/src/
    jena/Experimental/riot-output/src/main/
    jena/Experimental/riot-output/src/main/java/
    jena/Experimental/riot-output/src/main/java/dev/
    jena/Experimental/riot-output/src/main/java/dev/MainOutput.java
    jena/Experimental/riot-output/src/main/java/dev/MainWriter.java
    jena/Experimental/riot-output/src/main/java/dev/PROJECT_RiotWriter.java
    jena/Experimental/riot-output/src/main/java/riot/
    jena/Experimental/riot-output/src/main/java/riot/RDFWriterRegistry.java
    jena/Experimental/riot-output/src/main/java/riot/RiotSerializer.java
    jena/Experimental/riot-output/src/main/java/riot/RiotWriter.java
    jena/Experimental/riot-output/src/main/java/riot/WriterRIOTFactory.java
    jena/Experimental/riot-output/src/main/java/riot/other/
    jena/Experimental/riot-output/src/main/java/riot/other/GLib.java
    jena/Experimental/riot-output/src/main/java/riot/out/
    jena/Experimental/riot-output/src/main/java/riot/out/EscapeStr.java
    jena/Experimental/riot-output/src/main/java/riot/out/NodeFmtLib.java
    jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatter.java
    jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterBase.java
    jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterNT.java
    jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterTTL.java
    jena/Experimental/riot-output/src/main/java/riot/out/OutputUtils.java
    jena/Experimental/riot-output/src/main/java/riot/writer/
    jena/Experimental/riot-output/src/main/java/riot/writer/TW2.java
    jena/Experimental/riot-output/src/main/java/riot/writer/TriGWriter.java
    jena/Experimental/riot-output/src/main/java/riot/writer/TriGWriterBlocks.java
    jena/Experimental/riot-output/src/main/java/riot/writer/TriGWriterFlat.java
    jena/Experimental/riot-output/src/main/java/riot/writer/TurtleWriter2.java
    jena/Experimental/riot-output/src/main/java/riot/writer/TurtleWriterBlocks.java
    jena/Experimental/riot-output/src/main/java/riot/writer/TurtleWriterFlat.java
    jena/Experimental/riot-output/src/main/java/riot/writer/WriterConst.java
    jena/Experimental/riot-output/src/main/java/riot/writer/WriterContext.java
    jena/Experimental/riot-output/src/main/java/riot/writer/WriterStreamRDFBlocks.java
    jena/Experimental/riot-output/src/main/java/riot/writer/WriterStreamRDFFlat.java
    jena/Experimental/riot-output/src/main/resources/
    jena/Experimental/riot-output/src/test/
    jena/Experimental/riot-output/src/test/java/
    jena/Experimental/riot-output/src/test/java/riot/
    jena/Experimental/riot-output/src/test/java/riot/writer/
    jena/Experimental/riot-output/src/test/java/riot/writer/TestRIOTWriter.java
    jena/Experimental/riot-output/src/test/resources/
    jena/Experimental/riot-output/testing/
    jena/Experimental/riot-output/testing/RIOT/
    jena/Experimental/riot-output/testing/RIOT/Writer/
    jena/Experimental/riot-output/testing/RIOT/Writer/README.txt
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-00.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-01.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-02.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-03.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-04.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-05.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-06.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-07.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-08.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-09.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-10.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-11.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-12.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-13.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-14.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-15.ttl
    jena/Experimental/riot-output/testing/RIOT/Writer/writer-rt-16.ttl

Added: jena/Experimental/riot-output/.classpath
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/.classpath?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/.classpath (added)
+++ jena/Experimental/riot-output/.classpath Thu Jan 31 20:20:49 2013
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
+	<classpathentry including="**/*.java" kind="src" path="src/test/java"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/jena-arq"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/jena-core"/>
+	<classpathentry kind="lib" path="/home/afs/.m2/repo/org/apache/jena/jena-iri/0.9.5-SNAPSHOT/jena-iri-0.9.5-SNAPSHOT.jar"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/jena-tdb"/>
+	<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.6.4/slf4j-api-1.6.4.jar" sourcepath="M2_REPO/org/slf4j/slf4j-api/1.6.4/slf4j-api-1.6.4-sources.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-log4j12/1.6.4/slf4j-log4j12-1.6.4.jar" sourcepath="M2_REPO/org/slf4j/slf4j-log4j12/1.6.4/slf4j-log4j12-1.6.4-sources.jar"/>
+	<classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.16/log4j-1.2.16.jar" sourcepath="M2_REPO/log4j/log4j/1.2.16/log4j-1.2.16-sources.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/slf4j/jcl-over-slf4j/1.6.4/jcl-over-slf4j-1.6.4.jar" sourcepath="M2_REPO/org/slf4j/jcl-over-slf4j/1.6.4/jcl-over-slf4j-1.6.4-sources.jar"/>
+	<classpathentry kind="output" path="classes"/>
+</classpath>

Added: jena/Experimental/riot-output/.project
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/.project?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/.project (added)
+++ jena/Experimental/riot-output/.project Thu Jan 31 20:20:49 2013
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>riot-output</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: jena/Experimental/riot-output/D.trig
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/D.trig?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/D.trig (added)
+++ jena/Experimental/riot-output/D.trig Thu Jan 31 20:20:49 2013
@@ -0,0 +1,24 @@
+@prefix : <http://example/> .
+
+
+{ :s :p :o ;
+     :pppppp :o  ;
+     :pppppp :o  .
+  :s1 :qqq :o .
+}
+
+{
+  :longname1234567890 :p :o1 , :o2 .
+}
+
+
+:g1 { :s1 :p1 :o1 .} 
+:g1 { :s1 :p1 :o2 } 
+:g2 { :s2 :p2 :o2 ;
+          :p3 :o2  .
+	  :x :y 123 }
+{ :s :p :o . }
+
+@prefix ex: <http://example/> .
+
+{ ex:x ex:p ex:z }

Added: jena/Experimental/riot-output/D.ttl
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/D.ttl?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/D.ttl (added)
+++ jena/Experimental/riot-output/D.ttl Thu Jan 31 20:20:49 2013
@@ -0,0 +1,8 @@
+@prefix : <http://example/> .
+@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
+
+:s :pppp :o .
+:s :p (1 2) .
+:s :pppp :o .
+:s1 :pppp :o .

Added: jena/Experimental/riot-output/README.md
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/README.md?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/README.md (added)
+++ jena/Experimental/riot-output/README.md Thu Jan 31 20:20:49 2013
@@ -0,0 +1,4 @@
+riot-output
+===========
+
+Work area for maintenace of Turtle-related RDF output in Jena RIOT.
\ No newline at end of file

Added: jena/Experimental/riot-output/W.trig
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/W.trig?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/W.trig (added)
+++ jena/Experimental/riot-output/W.trig Thu Jan 31 20:20:49 2013
@@ -0,0 +1,31 @@
+@prefix : <http://example/> .
+@prefix ns: <http://example/ns#> .
+@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>  .
+
+{
+:s ns:p1 <http://other/planet> .
+:s ns:p2 123 .
+:s ns:p3 [] .
+:s a :T .
+}
+
+:g1 {
+:z :p1 _:a .
+:z :p2 _:a .
+
+<http://example2/LONGSUBJECT_URI> :p "foo" .
+:s1 <http://example2/LONGPREDICATE_URI>  "foo" .
+:s1 <http://example2/VERYVERY_VERY_VERY_LONGPREDICATE_URI>  "foo" .
+}
+
+:g2 {
+#:r ns:p4 (1 2 ) .
+
+:r ns:p5 [ ns:p "str" ] .
+
+:r ns:p5 [ ns:p [ ns:p 1 ] ] .
+:r ns:p5 [ ns:p [ ns:p 1 ; ns:p 2 ] ] .
+
+:r ns:p6 [ ns:q1 "str1" ; ns:q2 "str2" ] .
+:r ns:p7 [ ns:q1 "str1" ; ns:q2 "str2" ] .
+}
\ No newline at end of file

Added: jena/Experimental/riot-output/W.ttl
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/W.ttl?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/W.ttl (added)
+++ jena/Experimental/riot-output/W.ttl Thu Jan 31 20:20:49 2013
@@ -0,0 +1,27 @@
+@prefix :     <http://example/> .
+@prefix ns:   <http://example/ns#> .
+@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>  .
+
+## # bad list
+## :x :p3 _:bad .
+## 
+## _:bad rdf:rest (1 2 3) .
+## 
+## :x :p4 _:badz .
+## _:badz rdf:first (1 2 3) .
+## 
+# Bad: list tail is shared
+
+:x :q _:x0 .
+
+_:x0   rdf:first "cell-0" .
+_:x0   rdf:rest  _:x1 .
+
+:x1 :q _:x1 .
+
+_:x1   rdf:first "cell-1" .
+_:x1   rdf:rest  _:x2 .
+
+_:x2   rdf:first "cell-2" .
+_:x2   rdf:rest  rdf:nil .
+

Added: jena/Experimental/riot-output/src/main/java/dev/MainOutput.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/dev/MainOutput.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/dev/MainOutput.java (added)
+++ jena/Experimental/riot-output/src/main/java/dev/MainOutput.java Thu Jan 31 20:20:49 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 dev;
+
+
+import org.apache.jena.riot.RDFDataMgr ;
+import org.apache.jena.riot.system.StreamRDF ;
+import riot.writer.WriterStreamRDFBlocks ;
+
+public class MainOutput
+{
+    public static void main(String[] args)
+    {
+        StreamRDF dst = new WriterStreamRDFBlocks(System.out);
+        RDFDataMgr.parse(dst, "D.ttl") ;
+        System.out.println("--------") ;
+        dst = new WriterStreamRDFBlocks(System.out);
+        RDFDataMgr.parse(dst, "D.trig") ;
+        
+        System.out.println("DONE") ;
+        System.exit(0) ;
+    }
+}

Added: jena/Experimental/riot-output/src/main/java/dev/MainWriter.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/dev/MainWriter.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/dev/MainWriter.java (added)
+++ jena/Experimental/riot-output/src/main/java/dev/MainWriter.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,155 @@
+/**
+ * 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 dev;
+
+import java.io.ByteArrayInputStream ;
+import java.io.ByteArrayOutputStream ;
+import java.util.Iterator ;
+import java.util.Map.Entry ;
+
+import org.apache.jena.atlas.lib.StrUtils ;
+import org.apache.jena.iri.IRI ;
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.RDFDataMgr ;
+import org.apache.jena.riot.system.PrefixMap ;
+import org.apache.jena.riot.system.PrefixMapFactory ;
+import org.apache.jena.riot.system.StreamRDF ;
+import riot.RiotWriter ;
+import riot.writer.* ;
+
+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.query.Dataset ;
+import com.hp.hpl.jena.rdf.model.Model ;
+import com.hp.hpl.jena.rdf.model.ModelFactory ;
+import com.hp.hpl.jena.shared.PrefixMapping ;
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+
+public class MainWriter
+{
+    public static void main(String ...args)
+    {
+        writeTTL() ;
+        //writeTriG() ;
+    }
+    
+    public static void writeTriG()
+    {
+        Dataset ds = RDFDataMgr.loadDataset("W.trig") ;
+        TriGWriter.write(System.out, ds) ;
+    }
+    
+    public static void writeTTL()
+    {
+        String fn = "W.ttl" ;
+        
+        Model m = RDFDataMgr.loadModel(fn) ;
+        
+        if ( false )
+        {
+            System.out.println("# Write new (flat)") ;
+            TurtleWriterFlat.write(System.out, m) ;
+            System.out.println("----------------------------------") ;
+        }
+        if ( false )
+        {
+            System.out.println("# Write new (Pretty)") ;
+            TurtleWriter2.write(System.out, m) ;
+            System.out.println("----------------------------------") ;
+        }
+        if ( false )
+        {
+            System.out.println("# Write new (blocks)") ;
+            TurtleWriterBlocks.write(System.out, m) ;
+            System.out.println("----------------------------------") ;
+        }
+        if ( false )
+        {
+            System.out.println("# Write old") ;
+            m.write(System.out, "TTL") ;
+            System.out.println("----------------------------------") ;
+        }
+
+        System.out.println("# Write (Pretty)") ;
+        RiotWriter.write(System.out, m.getGraph(), Lang.TURTLE) ;
+        System.out.println("----------------------------------") ;
+
+        // check.
+        ByteArrayOutputStream out = new ByteArrayOutputStream() ;
+        RiotWriter.write(out, m.getGraph(), Lang.TURTLE) ;
+        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()) ;
+        String s = StrUtils.fromUTF8bytes(out.toByteArray()) ;
+
+        Model m2 = ModelFactory.createDefaultModel() ;
+        m2.read(in, null, "TTL") ;
+        if ( ! m.isIsomorphicWith(m2) )
+        {
+            System.out.println("**** DIFFERENT") ;
+            System.out.println("---------------") ;
+            m.write(System.out, "N-TRIPLES") ;
+            System.out.println("---------------") ;
+            m2.write(System.out, "N-TRIPLES") ;
+            System.out.println("---------------") ;
+        }
+
+    }
+
+    static void toStream(Graph g, StreamRDF dest)
+    {
+        PrefixMapping pmap = g.getPrefixMapping() ;
+        
+        dest.start();
+        Iterator<Entry<String,String>> iterp =  pmap.getNsPrefixMap().entrySet().iterator() ;
+        for ( ; iterp.hasNext() ; )
+        {
+            Entry<String,String> e = iterp.next() ;
+            dest.prefix(e.getKey(), e.getValue()) ;
+        }
+        
+        Iterator<Triple> iter = g.find(null, null, null) ;
+        for ( ; iter.hasNext() ; )
+            dest.triple(iter.next()) ;
+        dest.finish();
+    }
+    
+    static void toStream(DatasetGraph dsg, StreamRDF dest)
+    {
+        PrefixMap pmap = PrefixMapFactory.create() ;
+        pmap.putAll(dsg.getDefaultGraph().getPrefixMapping()) ;
+        Iterator<Node> gIter = dsg.listGraphNodes() ;
+        for ( ; gIter.hasNext() ; )
+        {
+            Node gn = gIter.next() ;
+            Graph g = dsg.getGraph(gn) ;
+            pmap.putAll(g.getPrefixMapping()) ;
+        }
+        
+        dest.start();
+        for ( Entry<String,IRI> e : pmap.getMapping().entrySet())
+            dest.prefix(e.getKey(), e.getValue().toString()) ;
+        
+        Iterator<Quad> iter = dsg.find(null, null, null, null) ;
+        for ( ; iter.hasNext() ; )
+            dest.quad(iter.next()) ;
+        dest.finish();
+    }
+}
+

Added: jena/Experimental/riot-output/src/main/java/dev/PROJECT_RiotWriter.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/dev/PROJECT_RiotWriter.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/dev/PROJECT_RiotWriter.java (added)
+++ jena/Experimental/riot-output/src/main/java/dev/PROJECT_RiotWriter.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,53 @@
+/**
+ * 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 dev;
+
+public class PROJECT_RiotWriter
+{
+    // Prefix map should generate Turtle legal abbrevs.
+    //  Variations.
+    
+    // Common super class for WriterStreamRDFBlocks/triples - it's the print(..) that is abstract.
+    // Do numbers.s
+    
+    // NT and NQ writers? Or are RIOT current OK?
+    
+    // Interface and organisation.
+    
+    // RiotWriter
+    
+    // Writing lists
+    // Clean code
+    //    TurtleWriter2
+    //    TW2
+
+    // TODO - check.
+
+    // PredicateObjectLists
+    //   type to front.
+    // Property order is:
+    // 1 - rdf:type (as "a")
+    // 2 - other rdf: rdfs: namespace items (sorted)
+    // 3 - all other properties, sorted by URI (not qname)  
+    //     same properties together - with and without object lists
+    
+    // TriG:
+    // Turtle plus
+}
+

Added: jena/Experimental/riot-output/src/main/java/riot/RDFWriterRegistry.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/RDFWriterRegistry.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/RDFWriterRegistry.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/RDFWriterRegistry.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,123 @@
+/**
+ * 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 riot;
+
+import static org.apache.jena.riot.RDFLanguages.N3 ;
+import static org.apache.jena.riot.RDFLanguages.NQUADS ;
+import static org.apache.jena.riot.RDFLanguages.NTRIPLES ;
+import static org.apache.jena.riot.RDFLanguages.RDFJSON ;
+import static org.apache.jena.riot.RDFLanguages.RDFXML ;
+import static org.apache.jena.riot.RDFLanguages.TRIG ;
+import static org.apache.jena.riot.RDFLanguages.TURTLE ;
+
+import java.io.OutputStream ;
+import java.util.HashMap ;
+import java.util.Map ;
+
+import org.apache.jena.riot.Lang ;
+import riot.writer.TurtleWriter2 ;
+
+import com.hp.hpl.jena.graph.Graph ;
+
+public class RDFWriterRegistry
+{
+    // Registry with the pretty write 
+    static Map<Lang, WriterRIOTFactory> registryPretty = new HashMap<Lang, WriterRIOTFactory>() ;
+    
+    // Registry with the scalable writer 
+    static Map<Lang, WriterRIOTFactory> registryStreaming = new HashMap<Lang, WriterRIOTFactory>() ;
+    
+    static WriterRIOTFactory wfactory = new WriterRIOTFactory() {
+        @Override
+        public RiotSerializer create(OutputStream out, Graph graph, Lang lang)
+        {
+            // Temporary hack.
+            RiotSerializer w = null ;
+
+            if ( TURTLE.equals(lang) )
+                w = createTurtle(out, graph) ;
+            else if ( NTRIPLES.equals(lang) )
+                w = createNTriples(out, graph) ;
+            else if ( N3.equals(lang) )
+                w = createN3(out, graph) ;
+            else if ( RDFJSON.equals(lang) )
+                w = createRDFJSON(out, graph) ;
+            else if ( RDFXML.equals(lang) )
+                w = createRDFJSON(out, graph) ;
+            else if ( TRIG.equals(lang) )
+                w = createTrig(out, graph) ;
+            else if ( NQUADS.equals(lang) )
+                w = createNQuads(out, graph) ;
+            return w ;
+        }} ;
+
+    static { init() ; }
+    
+    static void init()
+    {
+        registryPretty.put(TURTLE, wfactory) ;
+        registryPretty.put(NTRIPLES, wfactory) ;
+        registryPretty.put(N3, wfactory) ;
+        registryPretty.put(RDFJSON, wfactory) ;
+        registryPretty.put(TRIG, wfactory) ;
+        registryPretty.put(NQUADS, wfactory) ;
+    }
+    
+    public static WriterRIOTFactory getWriterFactory(Lang lang)
+    {
+        return registryPretty.get(lang) ;
+    }
+
+    private static RiotSerializer createTurtle(final OutputStream out, final Graph graph)
+    {
+        // TODO Temporary
+        return new RiotSerializer() {
+            @Override public void write() { TurtleWriter2.write(out, graph, graph.getPrefixMapping().getNsPrefixMap()) ; }
+            @Override public Lang getLang() { return TURTLE ; }
+        } ;
+    }
+
+    private static RiotSerializer createTurtleStreaming(final OutputStream out, final Graph graph)
+    {
+        // TODO Temporary
+        return new RiotSerializer() {
+            @Override public void write() { TurtleWriter2.write(out, graph, graph.getPrefixMapping().getNsPrefixMap()) ; }
+            @Override public Lang getLang() { return TURTLE ; }
+        } ;
+    }
+
+    private static RiotSerializer createNTriples(OutputStream out, Graph graph)
+    { return null ; }
+
+    private static RiotSerializer createRDFJSON(OutputStream out, Graph graph)
+    { return null ; }
+
+    private static RiotSerializer createN3(OutputStream out, Graph graph)
+    {
+        return createTurtle(out, graph) ;
+    }
+
+    private static RiotSerializer createTrig(OutputStream out, Graph graph)
+    { return null ; }
+
+    private static RiotSerializer createNQuads(OutputStream out, Graph graph)
+    { return null ; }
+
+}
+

Added: jena/Experimental/riot-output/src/main/java/riot/RiotSerializer.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/RiotSerializer.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/RiotSerializer.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/RiotSerializer.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,35 @@
+/**
+ * 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 riot;
+
+import org.apache.jena.riot.Lang ;
+
+/**
+ * A RIOT serilaizer for a language 
+ */
+public interface RiotSerializer
+{
+    /** 
+     * Perform the output process
+     */
+    public void             write() ;
+    public Lang             getLang() ;
+    
+    // Profile?
+}

Added: jena/Experimental/riot-output/src/main/java/riot/RiotWriter.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/RiotWriter.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/RiotWriter.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/RiotWriter.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,44 @@
+/** ;
+ * 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 riot;
+
+import java.io.OutputStream ;
+
+import org.apache.jena.atlas.lib.NotImplemented ;
+import org.apache.jena.riot.Lang ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+
+public class RiotWriter
+{
+    public static void write(OutputStream out, Graph graph, Lang lang)
+    {
+        WriterRIOTFactory wf = RDFWriterRegistry.getWriterFactory(lang) ;
+        RiotSerializer w = wf.create(out, graph, lang) ;
+        w.write() ;
+    }
+    
+    public static void write(OutputStream out, DatasetGraph datasetGraph, Lang lang)
+    {
+        throw new NotImplemented() ;
+    }
+}
+

Added: jena/Experimental/riot-output/src/main/java/riot/WriterRIOTFactory.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/WriterRIOTFactory.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/WriterRIOTFactory.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/WriterRIOTFactory.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,31 @@
+/**
+ * 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 riot;
+
+import java.io.OutputStream ;
+
+import org.apache.jena.riot.Lang ;
+
+import com.hp.hpl.jena.graph.Graph ;
+
+/** Factory for creating writers (usually one-time use but see a particular writer for details) */ 
+public interface WriterRIOTFactory
+{
+    public RiotSerializer create(OutputStream out, Graph graph, Lang lang) ;
+}

Added: jena/Experimental/riot-output/src/main/java/riot/other/GLib.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/other/GLib.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/other/GLib.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/other/GLib.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,131 @@
+/**
+ * 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 riot.other;
+
+import java.util.Iterator ;
+
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.iterator.Transform ;
+
+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.Quad ;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator ;
+
+/** A collection of Graph/Triple/Node related functions */
+public class GLib
+{
+    /** Convert null to Node.ANY */
+    public static Node nullAsAny(Node x) { return nullAsDft(x, Node.ANY) ; }
+    
+    /** Convert null to some default Node */
+    public static Node nullAsDft(Node x, Node dft) { return x==null ? dft : x ; }
+    
+    // DISTINCT means these are space using.
+    /** List the subjects in a graph (no duplicates) */
+    public static Iterator<Node> listSubjects(Graph graph)
+    {
+        ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, Node.ANY) ;
+        return Iter.iter(iter).map(projectTripeSubject).distinct() ;
+    }
+
+    /** List the predicates in a graph (no duplicates) */
+    public static Iterator<Node> listPredicates(Graph graph)
+    {
+        ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, Node.ANY) ;
+        return Iter.iter(iter).map(projectTripePredicate).distinct() ;
+    }
+    
+    /** List the objects in a graph (no duplicates) */
+    public static Iterator<Node> listObjects(Graph graph)
+    {
+        ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, Node.ANY) ;
+        return Iter.iter(iter).map(projectTripeObject).distinct() ;
+    }
+    
+    private static Transform<Quad, Triple> transformQuad2Triple = new Transform<Quad, Triple> () {
+        @Override
+        public Triple convert(Quad quad)    { return quad.asTriple() ; }
+    } ;
+
+    /** Project quads to triples */
+    public static Iter<Triple> quads2triples(Iterator<Quad> iter)
+    {
+        return Iter.iter(iter).map(transformQuad2Triple) ;
+    }
+
+    /** Project quad to graphname */
+    public static Iterator<Node> quad2graphName(Iterator<Quad> iter)
+    { return Iter.map(iter, projectQuadGraphName) ; }
+    
+    /** Project quad to graphname */
+    public static Iterator<Node> quad2subject(Iterator<Quad> iter)
+    { return Iter.map(iter, projectQuadSubject) ; }
+    
+    /** Project quad to predicate */
+    public static Iterator<Node> quad2predicate(Iterator<Quad> iter)
+    { return Iter.map(iter, projectQuadPredicate) ; }
+    
+    /** Project quad to object */
+    public static Iterator<Node> quad2object(Iterator<Quad> iter)
+    { return Iter.map(iter, projectQuadObject) ; }
+    
+    /** Project triple to subject */ 
+    public static Iterator<Node> triple2subject(Iterator<Triple> iter)
+    { return Iter.map(iter, projectTripeSubject) ; }
+    
+    /** Project triple to predicate */ 
+    public static Iterator<Node> triple2predicate(Iterator<Triple> iter)
+    { return Iter.map(iter, projectTripePredicate) ; }
+    
+    /** Project triple to object */ 
+    public static Iterator<Node> triple2object(Iterator<Triple> iter)
+    { return Iter.map(iter, projectTripeObject) ; }
+
+    /** Transform quad to graphname */
+    public static Transform<Quad, Node> projectQuadGraphName = new Transform<Quad, Node>() {
+        @Override  public Node convert(Quad quad) { return quad.getGraph() ; }
+    } ;
+    /** Transform quad to subject */
+    public static Transform<Quad, Node> projectQuadSubject = new Transform<Quad, Node>() {
+        @Override  public Node convert(Quad quad) { return quad.getSubject() ; }
+    } ;
+    /** Transform quad to predicate */
+    public static Transform<Quad, Node> projectQuadPredicate = new Transform<Quad, Node>() {
+        @Override public Node convert(Quad quad) { return quad.getPredicate() ; }
+    } ;
+    /** Transform quad to object */
+    public static Transform<Quad, Node> projectQuadObject = new Transform<Quad, Node>() {
+        @Override public Node convert(Quad quad) { return quad.getObject() ; }
+    } ;
+    /** Transform triple to subject */ 
+    public static Transform<Triple, Node> projectTripeSubject   = new Transform<Triple, Node>() {
+        @Override public Node convert(Triple triple) { return triple.getSubject() ; }
+    } ;
+    /** Transform triple to predicate */ 
+    public static Transform<Triple, Node> projectTripePredicate = new Transform<Triple, Node>() {
+        @Override public Node convert(Triple triple) { return triple.getPredicate() ; }
+    } ;
+    /** Transform triple to object */ 
+    public static Transform<Triple, Node> projectTripeObject    = new Transform<Triple, Node>() {
+        @Override public Node convert(Triple triple) { return triple.getObject() ; }
+    } ;
+}
+

Added: jena/Experimental/riot-output/src/main/java/riot/out/EscapeStr.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/out/EscapeStr.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/out/EscapeStr.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/out/EscapeStr.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,117 @@
+/*
+ * 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 riot.out;
+
+import org.apache.jena.atlas.io.IndentedLineBuffer ;
+import org.apache.jena.atlas.io.IndentedWriter ;
+
+import com.hp.hpl.jena.sparql.lang.ParserBase ;
+
+public class EscapeStr
+{
+    // Tests: TestOutput
+    // See also OutputLangUtils.outputEsc.
+    private final boolean ascii ;
+
+    public EscapeStr(boolean asciiOnly) { this.ascii = asciiOnly ; }
+
+    public void writeURI(IndentedWriter w, String s)
+    {
+        if ( ascii )
+            stringEsc(w, s, true, ascii) ;
+        else
+            // It's a URI - assume legal.
+            w.print(s) ;
+    }
+
+    public void writeStr(IndentedWriter w, String s) 
+    {
+        stringEsc(w, s, true, ascii) ;
+    }
+
+    public void writeStrMultiLine(IndentedWriter w, String s) 
+    {
+        // N-Triples does not have """
+        stringEsc(w, s, false, ascii) ;
+    }
+
+    // Utility
+    /*
+     * Escape characters in a string according to Turtle rules. 
+     */
+    public static String stringEsc(String s)
+    { return stringEsc(s, true, false) ; }
+
+    private static String stringEsc(String s, boolean singleLineString, boolean asciiOnly)
+    {
+        IndentedLineBuffer sb = new IndentedLineBuffer() ;
+        stringEsc(sb, s, singleLineString, asciiOnly) ;
+        return sb.toString() ;
+    }
+
+    public static void stringEsc(IndentedWriter out, String s, boolean singleLineString, boolean asciiOnly)
+    {
+        int len = s.length() ;
+        for (int i = 0; i < len; i++) {
+            char c = s.charAt(i);
+
+            // \\ Escape always possible.
+            if (c == '\\') 
+            {
+                out.print('\\') ;
+                out.print(c) ;
+                continue ;
+            }
+            if ( singleLineString )
+            {
+                if ( c == '"' )         { out.print("\\\""); continue ; }
+                else if (c == '\n')     { out.print("\\n");  continue ; }
+                else if (c == '\t')     { out.print("\\t");  continue ; }
+                else if (c == '\r')     { out.print("\\r");  continue ; }
+                else if (c == '\f')     { out.print("\\f");  continue ; }
+            }
+            // Not \-style esacpe. 
+            if ( c >= 32 && c < 127 )
+                out.print(c);
+            else if ( !asciiOnly )
+                out.print(c);
+            else
+            {
+                // Outside the charset range.
+                // Does not cover beyond 16 bits codepoints directly
+                // (i.e. \U escapes) but Java keeps these as surrogate
+                // pairs and will print as characters
+                out.print( "\\u") ;
+                OutputUtils.printHex(out, c, 4) ;
+            }
+        }
+    }
+
+    // Utilities to remove escapes
+
+    public static String unescapeStr(String s)
+    { return unescape(s, '\\') ; }
+    
+    // Worker function
+    public static String unescape(String s, char escape)
+    {
+        return ParserBase.unescape(s, escape, false,  -1, -1) ;
+        
+    }
+}

Added: jena/Experimental/riot-output/src/main/java/riot/out/NodeFmtLib.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/out/NodeFmtLib.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/out/NodeFmtLib.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/out/NodeFmtLib.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,201 @@
+/*
+ * 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 riot.out;
+
+import java.net.MalformedURLException ;
+import java.util.Map ;
+
+import org.apache.jena.atlas.io.IndentedLineBuffer ;
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.lib.Bytes ;
+import org.apache.jena.atlas.lib.Chars ;
+import org.apache.jena.iri.IRI ;
+import org.apache.jena.iri.IRIFactory ;
+import org.apache.jena.iri.IRIRelativize ;
+import org.apache.jena.riot.system.* ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.Triple ;
+import com.hp.hpl.jena.shared.PrefixMapping ;
+import com.hp.hpl.jena.sparql.ARQConstants ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+
+/** Presentation utilitiles for Nodes, Triples, Quads and more */ 
+public class NodeFmtLib
+{
+    // See OutputLangUtils.
+    // See and use EscapeStr
+    
+    static PrefixMap dftPrefixMap = PrefixMapFactory.create() ;
+    static {
+        PrefixMapping pm = ARQConstants.getGlobalPrefixMap() ;
+        Map<String, String> map = pm.getNsPrefixMap() ;
+        for ( Map.Entry<String, String> e : map.entrySet() )
+            dftPrefixMap.add(e.getKey(), e.getValue() ) ;
+    }
+
+    public static String str(Triple t)
+    {
+        return strNodes(t.getSubject(), t.getPredicate(),t.getObject()) ;
+    }
+
+    public static String str(Quad q)
+    {
+        return strNodes(q.getGraph(), q.getSubject(), q.getPredicate(), q.getObject()) ;
+    }
+    
+
+    // Worker
+    public static String strNodes(Node ... nodes)
+    {
+        IndentedLineBuffer sw = new IndentedLineBuffer() ;
+        boolean first = true ;
+        for ( Node n : nodes ) 
+        {
+            if ( ! first )
+            {
+                sw.append(" ") ;
+                first = false ;
+            }
+            str(sw, n) ;
+        }
+        return sw.toString() ; 
+    }
+
+    public static String str(Node n)
+    {
+        IndentedLineBuffer sw = new IndentedLineBuffer() ;
+        str(sw, n) ;
+        return sw.toString() ; 
+    }
+
+    private static final boolean onlySafeBNodeLabels = true ;
+
+    //public static String displayStr(Node n) { return serialize(n) ; }
+
+    public static void str(IndentedWriter w, Node n)
+    { serialize(w, n, null, null) ; }
+
+    public static void serialize(IndentedWriter w, Node n, Prologue prologue)
+    { serialize(w, n, prologue.getBaseURI(), prologue.getPrefixMap()) ; }
+
+    
+    public static void serialize(IndentedWriter w, Node n, String base, PrefixMap prefixMap)
+    {
+        if ( prefixMap == null )
+            prefixMap = dftPrefixMap ;
+        NodeFormatter formatter = new NodeFormatterTTL(base, prefixMap) ;
+        formatter.format(w, n) ;
+    }
+    
+    // ---- Blank node labels.
+    
+    // Strict N-triples only allows [A-Za-z][A-Za-z0-9]
+    static char encodeMarkerChar = 'X' ;
+
+    // These two form a pair to convert bNode labels to a safe (i.e. legal N-triples form) and back agains. 
+    
+    // Encoding is:
+    // 1 - Add a Letter 
+    // 2 - Hexify, as Xnn, anything outside ASCII A-Za-z0-9
+    // 3 - X is encoded as XX
+    
+    private static char LabelLeadingLetter = 'B' ; 
+    
+    public static String encodeBNodeLabel(String label)
+    {
+        StringBuilder buff = new StringBuilder() ;
+        // Must be at least one char and not a digit.
+        buff.append(LabelLeadingLetter) ;
+        
+        for ( int i = 0 ; i < label.length() ; i++ )
+        {
+            char ch = label.charAt(i) ;
+            if ( ch == encodeMarkerChar )
+            {
+                buff.append(ch) ;
+                buff.append(ch) ;
+            }
+            else if ( RiotChars.isA2ZN(ch) )
+                buff.append(ch) ;
+            else
+                Chars.encodeAsHex(buff, encodeMarkerChar, ch) ;
+        }
+        return buff.toString() ;
+    }
+
+    // Assumes that blank nodes only have characters in the range of 0-255
+    public static String decodeBNodeLabel(String label)
+    {
+        StringBuilder buffer = new StringBuilder() ;
+
+        if ( label.charAt(0) != LabelLeadingLetter )
+            return label ;
+        
+        // Skip first.
+        for ( int i = 1; i < label.length(); i++ )
+        {
+            char ch = label.charAt(i) ;
+            
+            if ( ch != encodeMarkerChar )
+            {
+                buffer.append(ch) ;
+            }
+            else
+            {
+                // Maybe XX or Xnn.
+                char ch2 = label.charAt(i+1) ;
+                if ( ch2 == encodeMarkerChar )
+                {
+                    i++ ;
+                    buffer.append(ch) ;
+                    continue ;
+                }
+                
+                // Xnn
+                i++ ;
+                char hiC = label.charAt(i) ;
+                int hi = Bytes.hexCharToInt(hiC) ;
+                i++ ;
+                char loC = label.charAt(i) ;
+                int lo = Bytes.hexCharToInt(loC) ;
+
+                int combined = ((hi << 4) | lo) ;
+                buffer.append((char) combined) ;
+            }
+        }
+
+        return buffer.toString() ;
+    }
+    
+    // ---- Relative URIs.
+    
+    static private int relFlags = IRIRelativize.SAMEDOCUMENT | IRIRelativize.CHILD ;
+    static public String abbrevByBase(String uri, String base)
+    {
+        if ( base == null )
+            return null ;
+        IRI baseIRI = IRIFactory.jenaImplementation().construct(base) ;
+        IRI rel = baseIRI.relativize(uri, relFlags) ;
+        String r = null ;
+        try { r = rel.toASCIIString() ; }
+        catch (MalformedURLException  ex) { r = rel.toString() ; }
+        return r ;
+    }
+}

Added: jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatter.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatter.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatter.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatter.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,53 @@
+/*
+ * 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 riot.out;
+
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+
+import com.hp.hpl.jena.graph.Node ;
+
+public interface NodeFormatter
+{
+    public void format(IndentedWriter w, Node n) ;
+
+    /** Node is guaranteed to be a URI node */
+    public void formatURI(IndentedWriter w, Node n) ;
+    public void formatURI(IndentedWriter w, String uriStr) ;
+    
+    public void formatVar(IndentedWriter w, Node n) ;
+    public void formatVar(IndentedWriter w, String name) ;
+    
+    /** Node is guaranteed to be a blank node */
+    public void formatBNode(IndentedWriter w, Node n) ;
+    public void formatBNode(IndentedWriter w, String label) ;
+    
+    /** Node is guaranteed to be a literal */
+    public void formatLiteral(IndentedWriter w, Node n) ;
+    
+    /** Plain string / xsd:string (RDF 1.1) */
+    public void formatLitString(IndentedWriter w, String lex) ;
+    
+    /** String with language tag */
+    public void formatLitLang(IndentedWriter w, String lex, String langTag) ;
+
+    /** Literal with datatype, not a simple literal, not an xsd:string (RDF 1.1), no language tag. */
+    public void formatLitDT(IndentedWriter w, String lex, String datatypeURI) ;
+    
+}

Added: jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterBase.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterBase.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterBase.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterBase.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,74 @@
+/*
+ * 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 riot.out;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.sparql.ARQInternalErrorException ;
+
+/** Provide implementations of the operations of NodeFormatter in terms
+ * of core operations for each node type.
+ */
+public abstract class NodeFormatterBase implements NodeFormatter
+{
+    @Override
+    public void format(IndentedWriter w, Node n)
+    {
+        if ( n.isBlank() )
+            formatBNode(w, n) ;
+        else if ( n.isURI() )
+            formatURI(w, n) ;
+        else if ( n.isLiteral() )
+            formatLiteral(w, n) ;
+        else if ( n.isVariable() )
+            formatVar(w, n) ;
+        else if ( Node.ANY.equals(n) )
+            w.print("ANY") ;
+        else
+            throw new ARQInternalErrorException("Unknow node type: "+n) ;
+    }
+    
+    @Override
+    public void formatURI(IndentedWriter w, Node n)         { formatURI(w, n.getURI()) ; }
+
+    @Override
+    public void formatBNode(IndentedWriter w, Node n)       { formatBNode(w, n.getBlankNodeLabel()) ; }
+
+    @Override
+    public void formatLiteral(IndentedWriter w, Node n)
+    {
+        String dt = n.getLiteralDatatypeURI() ;
+        String lang = n.getLiteralLanguage() ;
+        String lex = n.getLiteralLexicalForm() ;
+        
+        if ( dt == null )
+        {
+            if ( lang == null || lang.equals("") )
+                formatLitString(w, lex) ;
+            else
+                formatLitLang(w, lex,lang) ;
+        }
+        else
+            formatLitDT(w, lex, dt) ;
+    }
+
+    @Override
+    public void formatVar(IndentedWriter w, Node n)         { formatVar(w, n.getName()) ; }
+}

Added: jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterNT.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterNT.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterNT.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterNT.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,86 @@
+/*
+ * 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 riot.out;
+
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+
+public class NodeFormatterNT extends NodeFormatterBase
+{
+    // Formatting for NTriples 
+    // Turtles extends this class to intercept forms it can do better.
+
+    private final EscapeStr escapeProc ; 
+
+    public NodeFormatterNT() { this(true) ; }
+
+    protected NodeFormatterNT(boolean asciiOnly) { escapeProc = new EscapeStr(asciiOnly) ;}
+
+    @Override
+    public void formatURI(IndentedWriter w, String uriStr)
+    {
+        w.print('<') ;
+        w.print(uriStr) ;
+        w.print('>') ;
+    }
+
+    @Override
+    public void formatVar(IndentedWriter w, String name)
+    {
+        w.print('?') ;
+        w.print(name) ;
+    }
+
+    @Override
+    public void formatBNode(IndentedWriter w, String label)
+    {
+        w.print("_:") ;
+        String lab = NodeFmtLib.encodeBNodeLabel(label) ;
+        w.print(lab) ;
+    }
+
+    @Override
+    public void formatLitString(IndentedWriter w, String lex)
+    {
+        writeEscaped(w, lex) ;
+    }
+
+    private void writeEscaped(IndentedWriter w, String lex)
+    {
+        w.print('"') ;
+        escapeProc.writeStr(w, lex) ;
+        w.print('"') ;
+    }
+
+    @Override
+    public void formatLitLang(IndentedWriter w, String lex, String langTag)
+    {
+        writeEscaped(w, lex) ;
+        w.print('@') ;
+        w.print(langTag) ;
+    }
+
+    @Override
+    public void formatLitDT(IndentedWriter w, String lex, String datatypeURI)
+    {
+        writeEscaped(w, lex) ;
+        w.print("^^") ;
+        formatURI(w, datatypeURI) ;
+    }
+}

Added: jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterTTL.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterTTL.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterTTL.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/out/NodeFormatterTTL.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,341 @@
+/*
+ * 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 riot.out;
+
+import java.net.MalformedURLException ;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.lib.Pair ;
+import org.apache.jena.iri.IRI ;
+import org.apache.jena.iri.IRIFactory ;
+import org.apache.jena.iri.IRIRelativize ;
+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.RiotChars ;
+
+import com.hp.hpl.jena.datatypes.xsd.XSDDatatype ;
+import com.hp.hpl.jena.graph.Node ;
+
+public class NodeFormatterTTL extends NodeFormatterNT
+{
+    private final NodeToLabel nodeToLabel ;
+    private final PrefixMap prefixMap ;
+    private final String baseIRI ; 
+    
+    // Replace with a single "OutputPolicy"
+    public NodeFormatterTTL(String baseIRI , PrefixMap prefixMap) //OutputPolicy outputPolicy)
+    {
+        this(baseIRI, prefixMap, NodeToLabel.createBNodeByLabelEncoded()) ;
+    }
+    
+   public NodeFormatterTTL(String baseIRI , PrefixMap prefixMap, NodeToLabel nodeToLabel)
+   {
+       super(false) ;
+       this.nodeToLabel = nodeToLabel ;
+       if ( prefixMap == null )
+           prefixMap = PrefixMapFactory.create() ;
+       this.prefixMap = prefixMap ;
+       this.baseIRI = baseIRI ;
+   }
+    
+    @Override
+    public void formatURI(IndentedWriter w, String uriStr)
+    {
+        Pair<String, String> pName = prefixMap.abbrev(uriStr) ;
+        // Check if legal
+        if ( pName != null )
+        {
+            // Check legal - need to check legal, not for illegal.
+            String pref = pName.getLeft() ;
+            String ln = pName.getRight() ;
+            if ( safeForPrefix(pref) && safeForPrefixLocalname(ln) )
+            {
+                w.print(pName.getLeft()) ;
+                w.print(':') ;
+                w.print(pName.getRight()) ;
+                return ;
+            }
+        }
+
+        // Attempt base abbreviation.
+        if ( baseIRI != null )
+        {
+            String x = abbrevByBase(uriStr, baseIRI) ;
+            if ( x != null )
+            {
+                w.print('<') ;
+                w.print(x) ;
+                w.print('>') ;
+                return ;
+            }
+        }
+
+        // else
+        super.formatURI(w, uriStr) ;
+    }
+    
+    static private int relFlags = IRIRelativize.SAMEDOCUMENT | IRIRelativize.CHILD ;
+    static private String abbrevByBase(String uri, String base)
+    {
+        if ( base == null )
+            return null ;
+        IRI baseIRI = IRIFactory.jenaImplementation().construct(base) ;
+        IRI rel = baseIRI.relativize(uri, relFlags) ;
+        String r = null ;
+        try { r = rel.toASCIIString() ; }
+        catch (MalformedURLException  ex) { r = rel.toString() ; }
+        return r ;
+    }
+
+    /*private-testing*/ 
+    static boolean safeForPrefix(String str)
+    {
+        int N = str.length() ;
+        if ( N == 0 ) return true ;
+        int idx = 0 ;
+        idx = skip1_PN_CHARS_BASE(str, idx) ;
+        if ( idx == -1 ) return false ;
+        idx = skipAny_PN_CHARS_or_DOT(str, idx) ;
+        if ( idx == -1 ) return false ;
+        if ( idx == N ) return true ;
+        idx = skip1_PN_CHARS(str, idx) ;
+        if ( idx == -1 ) return false ;
+        return ( idx == N ) ;
+    }
+
+//    @Override
+//    public void formatVar(IndentedWriter w, String name)
+
+//    @Override
+//    public void formatBNode(IndentedWriter w, String label)
+    
+    @Override
+    public void formatBNode(IndentedWriter w, Node n)
+    {
+        String x = nodeToLabel.get(null, n) ;
+        w.print(x) ; 
+    }
+
+//    @Override
+//    public void formatLitString(IndentedWriter w, String lex)
+
+//    @Override
+//    public void formatLitLang(IndentedWriter w, String lex, String langTag)
+
+    /*private-testing*/ static boolean safeForPrefixLocalname(String str)
+    {
+        int N = str.length() ;
+        if ( N == 0 ) return true ;
+        int idx = 0 ;
+        idx = skip1_PN_CHARS_U_or_029(str, idx) ;
+        if ( idx == -1 ) return false ;
+        idx = skipAny_PN_CHARS_or_DOT(str, idx) ;
+        if ( idx == -1 ) return false ;
+        if ( idx == N ) return true ;
+        idx = skip1_PN_CHARS(str, idx) ;
+        return ( idx == N ) ;
+    }
+
+    private static boolean is_PN_CHARS_BASE(int ch)    { return RiotChars.isAlpha(ch) ; }
+    private static boolean is_PN_CHARS_U(int ch)       { return is_PN_CHARS_BASE(ch) || ch == '_' ; }
+    private static boolean is_PN_CHARS(int ch)         { return is_PN_CHARS_U(ch) || ch == '-' || RiotChars.isDigit(ch) || isCharsExtra(ch) ; }
+    
+    public static boolean isCharsExtra(int ch)
+    {
+        return ch == '\u00B7' || RiotChars.range(ch, '\u0300', '\u036F') || RiotChars.range(ch, '\u203F', '\u2040')  ;  
+    }
+    
+    private static int skip1_PN_CHARS_U_or_029(String str, int idx)
+    {
+        char ch = str.charAt(idx) ;
+        if ( is_PN_CHARS_U(ch) ) return idx+1 ;
+        if ( RiotChars.isDigit(ch) ) return idx+1 ;
+        return -1 ;
+    }
+
+    private static int skip1_PN_CHARS_BASE(String str, int idx)
+    {
+        char ch = str.charAt(idx) ;
+        if ( is_PN_CHARS_BASE(ch) ) return idx+1 ;
+        return -1 ;
+    }
+
+    private static int skipAny_PN_CHARS_or_DOT(String str, int idx)
+    {
+        int N = str.length() ;
+        for ( int i = idx ; i < N ; i++ )
+        {
+            char ch = str.charAt(i) ;
+            if ( ! is_PN_CHARS(ch) && ch != '.' ) return i ;
+        }
+        return N ;
+    }
+
+    private static int skip1_PN_CHARS(String str, int idx)
+    {
+        char ch = str.charAt(idx) ;
+        if ( is_PN_CHARS(ch) ) return idx+1 ;
+        return -1 ;
+    }
+
+    private static final String dtDecimal   = XSDDatatype.XSDdecimal.getURI() ;
+    private static final String dtInteger   = XSDDatatype.XSDinteger.getURI() ;
+    private static final String dtDouble    = XSDDatatype.XSDdouble.getURI() ;
+    private static final String dtBoolean   = XSDDatatype.XSDboolean.getURI() ;
+
+    @Override
+    public void formatLitDT(IndentedWriter w, String lex, String datatypeURI)
+    {
+        if ( dtDecimal.equals(datatypeURI) )
+        {
+            if ( validDecimal(lex) )
+            {
+                w.print(lex) ;
+                return ;
+            }
+        }
+        else if ( dtInteger.equals(datatypeURI) )
+        {
+            if ( validInteger(lex) )
+            {
+                w.print(lex) ;
+                return ;
+            }
+        }
+        if ( dtDouble.equals(datatypeURI) )
+        {
+            if ( validDouble(lex) )
+            {
+                w.print(lex) ;
+                return ; 
+            }
+        }
+        // Boolean
+        if ( dtBoolean.equals(datatypeURI) )
+        {
+            // We leave "0" and "1" as-is assumign that if written like that, there was a reason.
+            if ( lex.equals("true") || lex.equals("false") )
+            {
+                w.print(lex) ;
+                return ; 
+            }
+        }
+        
+        // else.
+        super.formatLitDT(w, lex, datatypeURI) ;
+    }
+
+
+    private static boolean validInteger(String lex)
+    {
+        int N = lex.length() ;
+        if ( N == 0 ) return false ;
+        int idx = 0 ;
+        
+        idx = skipSign(lex, idx) ;
+        idx = skipDigits(lex, idx) ;
+        return ( idx == N ) ;
+    }
+    
+    private static boolean validDecimal(String lex)
+    {
+        // case : In N3, "." illegal, as is "+." and -." but legal in Turtle.
+        int N = lex.length() ;
+        if ( N <= 1 ) return false ;
+        int idx = 0 ;
+        
+        idx = skipSign(lex, idx) ;
+        idx = skipDigits(lex, idx) ;    // Maybe none.
+        
+        // DOT required.
+        if ( idx >= N ) return false ;
+        
+        char ch = lex.charAt(idx) ;
+        if ( ch != '.' ) return false ;
+        idx++ ;
+        // Digit required.
+        if ( idx >= N ) return false ;
+        idx = skipDigits(lex, idx) ;
+        return ( idx == N )  ;
+    }
+    
+    private static boolean validDouble(String lex)
+    {
+        int N = lex.length() ;
+        if ( N == 0 ) return false ;
+        int idx = 0 ;
+        
+        // Decimal part (except 12. is legal)
+        
+        idx = skipSign(lex, idx) ;
+        
+        int idx2 = skipDigits(lex, idx) ;
+        boolean initialDigits = ( idx != idx2) ;
+        idx = idx2 ;
+        // Exponent required.
+        if ( idx >= N ) return false ;
+        char ch = lex.charAt(idx) ;
+        if ( ch == '.' )
+        {
+            idx++ ;
+            if ( idx >= N ) return false ;
+            idx2 = skipDigits(lex, idx) ;
+            boolean trailingDigits = ( idx != idx2 ) ;
+            idx = idx2 ;
+            if ( idx >= N ) return false ;
+            if ( !initialDigits && !trailingDigits ) return false ;
+        }
+        // "e" or "E"
+        ch = lex.charAt(idx) ;
+        if ( ch != 'e' && ch != 'E' ) return false ;
+        idx++ ;
+        if ( idx >= N ) return false ;
+        idx = skipSign(lex, idx) ;
+        if ( idx >= N ) return false ;  // At least one digit.
+        idx = skipDigits(lex, idx) ;
+        return ( idx == N )  ;
+    }
+    
+    /** Skip digits [0-9] and return the index just after the digits,
+     * which may be beyond the length of the string.
+     * May skip zero.
+     */
+    private static int skipDigits(String str, int start)
+    {
+        int N = str.length() ;
+        for ( int i = start ; i < N ; i++ )
+        {
+            char ch = str.charAt(i) ;
+            if ( ! RiotChars.isDigit(ch) )
+                return i ;
+        } 
+        return N ;
+    }
+    
+    /** Skip any plus or minus */
+    private static int skipSign(String str, int idx)
+    {
+        int N = str.length() ;
+        char ch = str.charAt(idx) ;
+        if ( ch == '+' || ch == '-' )
+            return idx + 1 ;
+        return idx ;
+    }
+}

Added: jena/Experimental/riot-output/src/main/java/riot/out/OutputUtils.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/out/OutputUtils.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/out/OutputUtils.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/out/OutputUtils.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,78 @@
+/*
+ * 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 riot.out;
+
+import java.io.IOException ;
+import java.io.Writer ;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.lib.BitsInt ;
+import org.apache.jena.atlas.lib.Chars ;
+
+public class OutputUtils
+{
+    /** Print the number x in width hex chars.  x must fit */
+    public static void printHex(StringBuilder out, int x, int width)
+    {
+        for ( int i = width-1 ; i >= 0 ; i-- )
+            x = oneHex(out, x, i) ;
+    }
+
+    /** Print one hex digit of the number */
+    public static int oneHex(StringBuilder out, int x, int i)
+    {
+        int y = BitsInt.unpack(x, 4*i, 4*i+4) ;
+        char charHex = Chars.hexDigitsUC[y] ;
+        out.append(charHex) ; 
+        return BitsInt.clear(x, 4*i, 4*i+4) ;
+    }
+    
+    /** Print the number x in width hex chars.  x must fit */
+    public static void printHex(Writer out, int x, int width)
+    {
+        for ( int i = width-1 ; i >= 0 ; i-- )
+            x = oneHex(out, x, i) ;
+    }
+
+    /** Print one hex digit of the numer */
+    public static int oneHex(Writer out, int x, int i)
+    {
+        int y = BitsInt.unpack(x, 4*i, 4*i+4) ;
+        char charHex = Chars.hexDigitsUC[y] ;
+        try { out.write(charHex) ; } catch (IOException ex) {} 
+        return BitsInt.clear(x, 4*i, 4*i+4) ;
+    }
+
+    /** Print the number x in width hex chars.  x must fit */
+    public static void printHex(IndentedWriter out, int x, int width)
+    {
+        for ( int i = width-1 ; i >= 0 ; i-- )
+            x = oneHex(out, x, i) ;
+    }
+
+    /** Print one hex digit of the number */
+    public static int oneHex(IndentedWriter out, int x, int i)
+    {
+        int y = BitsInt.unpack(x, 4*i, 4*i+4) ;
+        char charHex = Chars.hexDigitsUC[y] ;
+        out.print(charHex) ; 
+        return BitsInt.clear(x, 4*i, 4*i+4) ;
+    }
+    
+}

Added: jena/Experimental/riot-output/src/main/java/riot/writer/TW2.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/writer/TW2.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/writer/TW2.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/writer/TW2.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,339 @@
+/**
+ * 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 riot.writer;
+
+import static riot.writer.WriterConst.PREFIX_IRI ;
+import static riot.writer.WriterConst.RDF_First ;
+import static riot.writer.WriterConst.RDF_Nil ;
+import static riot.writer.WriterConst.RDF_Rest ;
+
+import java.util.* ;
+import java.util.Map.Entry ;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.lib.Pair ;
+import riot.out.NodeFormatter ;
+
+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.util.FmtUtils ;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator ;
+//import com.hp.hpl.jena.sparql.util.FmtUtils ;
+
+/** Support code for the RIOT TurtleWriter */ 
+public class TW2
+{
+    
+    static void writePrefixes(WriterContext cxt, Map<String, String> prefixMap)
+    {
+        writePrefixes(cxt.out, prefixMap) ;
+    }
+    
+    static void writePrefixes(IndentedWriter out, Map<String, String> prefixMap)
+    {
+        if ( ! prefixMap.isEmpty() )
+        {
+            // prepare?
+            for ( Map.Entry <String, String> e : prefixMap.entrySet() )
+            {
+                out.print("@prefix ") ;
+                out.print(e.getKey()) ;
+                out.print(": ") ;
+                out.pad(PREFIX_IRI) ;
+                out.print("<") ;
+                out.print(e.getValue()) ;   // Check?
+                out.print(">") ;
+                out.print(" .") ;
+                out.println() ;
+            }
+        }
+    }
+
+    // Single, multi-function, pass over the graph 
+    // It alread scans all objects.
+
+    /** Find all list heads and all nodes in well-formed lists.
+     * Return a (list head -> Elements map), list elements)  
+     */
+    static void findLists(WriterContext cxt)
+    {
+        // HashSets for use during parsing.
+        Map<Node, List<Node>> lists = new HashMap<Node, List<Node>>() ;
+        // Lists that are printed as free standing lists. 
+        Map<Node, List<Node>> freeLists = new HashMap<Node, List<Node>>() ;
+        // Lists that are shared 
+        Map<Node, List<Node>> nLinkedLists = new HashMap<Node, List<Node>>() ;
+        
+        Collection<Node> listElts = new HashSet<Node>() ;
+        List<Triple> tails = triples(cxt.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(cxt, t.getSubject(), listElts2) ;
+            if ( p != null )
+            {
+                Node headElt = p.getLeft() ; 
+                // Free standing?
+                List<Node> elts = p.getRight() ;
+                long numLinks = countTriples(cxt.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.
+                    // TODO Can't print the list in abbreviated form as we need to name the head.
+                    // Take out first element, print rest normally, new head is a one-connected node.
+                    //OR do in the printing. (N3 has "_:b :-")
+                    nLinkedLists.put(headElt, elts) ;
+                }
+                listElts.addAll(listElts2) ;
+            }
+        }
+        cxt.freeLists = freeLists ;
+        cxt.lists = lists ;
+        cxt.listElts = listElts ;
+        cxt.nLinkedLists= nLinkedLists ; 
+    }
+//
+//    // Return is the elements
+//    static Pair<Collection<Node>, Collection<Node>>  findList1(Node lastElt, WriterContext cxt)
+//    {
+//        
+//    }
+    
+    
+    // return head elt node, list of elements.
+    private static Pair<Node, List<Node>> followTailToHead(WriterContext cxt, 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 ;
+        final Graph graph = cxt.graph ;
+        
+        for ( ; ; )
+        {
+            if ( ! validListElement(graph, 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 = 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 = triples(graph, null, null, x) ;
+            long numRest = 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 static boolean validListElement(Graph graph, Node x, List<Triple> acc)
+    {
+        Triple t1 = triple1(graph, x, RDF_Rest, null) ; // Which we came up to get here :-(
+        if ( t1 == null )
+            return false ;
+        Triple t2 = triple1(graph, x, RDF_First, null) ;
+        if ( t2 == null )
+            return false ;
+        long N = countTriples(graph, x, null, null) ;
+        if ( N != 2 )
+            return false ;
+        acc.add(t1) ;
+        acc.add(t2) ;
+        return true ;
+    }
+
+    static final boolean recordObjectMisses = true ; 
+    
+    /** Find all embeddable objects */  
+    @SuppressWarnings("null")
+    static void findOneConnectedBNodeObjects(WriterContext cxt)
+    {
+        Set<Node> bNodesObj1 = new HashSet<Node>()  ;        // The subject of exactly one triple.
+        Set<Node> rejects = recordObjectMisses ? new HashSet<Node>() : null ;      // Nodes known not to meet the requirement.
+
+        ExtendedIterator<Triple> iter = cxt.graph.find(Node.ANY, Node.ANY, Node.ANY) ;
+        try {
+            for ( ; iter.hasNext() ; )
+            {
+                Triple t = iter.next() ;
+                Node obj = t.getObject() ;
+                if ( ! obj.isBlank() )
+                    continue ;
+                if ( rejects != null && rejects.contains(obj) )
+                    continue ;
+                // No point checking bNodesObj1.
+                Node n = connectedOnce(cxt.graph, obj) ;
+                if ( n != null )
+                    bNodesObj1.add(n) ;
+            }
+        } finally { iter.close() ; }
+        cxt.nestedObjects = bNodesObj1 ;
+    }
+
+    static Node connectedOnce(Graph graph, Node obj)
+    {
+        ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, obj) ;
+        int count = 0 ;
+        try {
+            if ( ! iter.hasNext() ) return null ;
+            iter.next() ;
+            if ( ! iter.hasNext() ) return obj ;
+            return null ;
+        } finally { iter.close() ; }
+    }
+    
+    static Collection<Triple> triplesOfSubject(Graph graph, Node subj)
+    {
+        return triples(graph, subj, Node.ANY, Node.ANY) ;
+    }
+
+    /* Get all the triples for the graph.find */
+    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 */
+    private 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() ; }
+    }
+
+    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. */
+    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() ; }
+    }
+
+    static void writeNode(WriterContext cxt, Node node)
+    {
+        writeNode(cxt.out, cxt.nodeFmt, node) ;
+    }
+    
+    static void writeNode(IndentedWriter out, NodeFormatter fmt,Node node)
+    {
+        fmt.format(out, node) ;
+    }
+        
+    static void writeNode(IndentedWriter out, Map<String, String> prefixMap, Node node)
+    {
+        //TODO Temporary.
+        // See RIOT NodeFormatter
+        if ( node.isURI() )
+        {
+            String iri = node.getURI() ;
+            // Crude.
+            String x = abbreviate(iri, prefixMap) ;
+            if ( x != null )
+            {
+                out.print(x) ;
+                return ;
+            }
+        }
+        out.print(FmtUtils.stringForNode(node)) ;
+    }
+
+    /** Abbreviate an IRI or return null */
+    private static String abbreviate(String uriStr, Map<String, String> prefixMap)
+    {
+        for ( Entry<String, String> e : prefixMap.entrySet())
+        {
+            String prefix = e.getValue().toString() ;
+            
+            if ( uriStr.startsWith(prefix) )
+            {
+                String ln = uriStr.substring(prefix.length()) ;
+                if ( strSafeFor(ln, '/') && strSafeFor(ln, '#') && strSafeFor(ln, ':') )
+                    return e.getKey()+":"+ln ;
+            }
+        }
+        return null ;
+    }
+
+    static boolean strSafeFor(String str, char ch) { return str.indexOf(ch) == -1 ; }
+
+    private static void flush(IndentedWriter out) { out.flush() ; }
+
+    static void print(WriterContext cxt,String string)
+    {
+        cxt.out.print(string) ;
+        flush(cxt.out) ;
+    }
+
+    static void pad(WriterContext cxt,int col)
+    {
+        cxt.out.pad(col, true) ;
+    }
+}
+

Added: jena/Experimental/riot-output/src/main/java/riot/writer/TriGWriter.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/writer/TriGWriter.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/writer/TriGWriter.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/writer/TriGWriter.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,76 @@
+/**
+ * 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 riot.writer;
+
+import java.io.OutputStream ;
+import java.util.Iterator ;
+import java.util.Map ;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.query.Dataset ;
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+
+public class TriGWriter
+{
+    // UNFINISHED
+    public static final int GRAPH_INDENT = 4 ;
+    
+    public static void write(OutputStream out, Dataset dataset)
+    {
+        write(out, dataset.asDatasetGraph(), dataset.getDefaultModel().getNsPrefixMap()) ;
+    }
+    
+    public static void write(OutputStream out, DatasetGraph dsg,  Map<String, String> prefixMap)
+    {
+        IndentedWriter iOut = new IndentedWriter(out, false) ;
+        Iterator<Node> graphNames = dsg.listGraphNodes() ;
+        
+        writeGraph(iOut, null, dsg.getDefaultGraph(),  prefixMap) ;
+        
+        for ( ; graphNames.hasNext() ; )
+        {
+            iOut.println() ;
+            Node gn = graphNames.next() ;
+            writeGraph(iOut, gn, dsg.getGraph(gn),  prefixMap) ;
+        }
+        iOut.flush() ;
+    }
+
+    
+    private static void writeGraph(IndentedWriter out, Node name, Graph graph,  Map<String, String> prefixMap)
+    {
+        if ( name != null )
+        {
+            TW2.writeNode(out, prefixMap, name) ;
+            out.print("  ") ;
+        }
+        out.println("{") ;
+        out.incIndent(GRAPH_INDENT) ;
+        TurtleWriter2.write(out, graph, prefixMap) ;
+        
+        out.decIndent(GRAPH_INDENT) ;
+        out.ensureStartOfLine() ;
+        out.println("}") ;
+    }
+
+}
+

Added: jena/Experimental/riot-output/src/main/java/riot/writer/TriGWriterBlocks.java
URL: http://svn.apache.org/viewvc/jena/Experimental/riot-output/src/main/java/riot/writer/TriGWriterBlocks.java?rev=1441178&view=auto
==============================================================================
--- jena/Experimental/riot-output/src/main/java/riot/writer/TriGWriterBlocks.java (added)
+++ jena/Experimental/riot-output/src/main/java/riot/writer/TriGWriterBlocks.java Thu Jan 31 20:20:49 2013
@@ -0,0 +1,49 @@
+/**
+ * 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 riot.writer;
+
+import java.util.Iterator ;
+import java.util.Map ;
+import java.util.Map.Entry ;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.riot.system.StreamRDF ;
+
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+
+public class TriGWriterBlocks
+{
+    public static void write(IndentedWriter out, DatasetGraph graph, Map<String, String> prefixes) 
+    {
+        StreamRDF dest = new WriterStreamRDFBlocks(out) ;
+        dest.start() ;
+        for ( Entry<String, String> e : prefixes.entrySet() )
+            dest.prefix(e.getKey(), e.getValue()) ;
+        Iterator<Quad> iter = graph.find(null, null, null, null) ;
+        for ( ; iter.hasNext() ; )
+        {
+            Quad q = iter.next() ;
+            dest.quad(q) ;
+        }
+        dest.finish() ;
+    }
+
+}
+