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 2011/12/26 21:57:13 UTC
svn commit: r1224807 - in /incubator/jena/Scratch/AFS/Dev/trunk: ./
src/main/java/riot/
Author: andy
Date: Mon Dec 26 20:57:13 2011
New Revision: 1224807
URL: http://svn.apache.org/viewvc?rev=1224807&view=rev
Log:
Turtle writer rewrite (work-in-progress)
Added:
incubator/jena/Scratch/AFS/Dev/trunk/D.trig
incubator/jena/Scratch/AFS/Dev/trunk/D.ttl
incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TW2.java
incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TriGWriter.java
incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriter2.java
incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriterBlocks.java
incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriterFlat.java
Added: incubator/jena/Scratch/AFS/Dev/trunk/D.trig
URL: http://svn.apache.org/viewvc/incubator/jena/Scratch/AFS/Dev/trunk/D.trig?rev=1224807&view=auto
==============================================================================
--- incubator/jena/Scratch/AFS/Dev/trunk/D.trig (added)
+++ incubator/jena/Scratch/AFS/Dev/trunk/D.trig Mon Dec 26 20:57:13 2011
@@ -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: incubator/jena/Scratch/AFS/Dev/trunk/D.ttl
URL: http://svn.apache.org/viewvc/incubator/jena/Scratch/AFS/Dev/trunk/D.ttl?rev=1224807&view=auto
==============================================================================
--- incubator/jena/Scratch/AFS/Dev/trunk/D.ttl (added)
+++ incubator/jena/Scratch/AFS/Dev/trunk/D.ttl Mon Dec 26 20:57:13 2011
@@ -0,0 +1,25 @@
+@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 .
+
+: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" .
+
+#: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" ] .
Added: incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TW2.java
URL: http://svn.apache.org/viewvc/incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TW2.java?rev=1224807&view=auto
==============================================================================
--- incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TW2.java (added)
+++ incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TW2.java Mon Dec 26 20:57:13 2011
@@ -0,0 +1,120 @@
+/**
+ * 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.util.Collection ;
+import java.util.HashSet ;
+import java.util.Iterator ;
+import java.util.Set ;
+
+import org.openjena.atlas.iterator.Iter ;
+import org.openjena.atlas.iterator.Transform ;
+import org.openjena.atlas.lib.Pair ;
+
+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 ;
+
+/** Support code for the RIOT TurtleWriter */
+public class TW2
+{
+ static final boolean recordObjectMisses = true ;
+
+ // Single, multi-function, pass over the graph
+
+ /** Find all embeddable objects */
+ @SuppressWarnings("null")
+ static Pair<Set<Node>, Set<Triple>> findOneConnectedBNodeObjects(Graph graph)
+ {
+ ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, Node.ANY) ;
+
+ Set<Node> bNodesObj1 = new HashSet<Node>() ; // The subject of exactly one triple.
+ Set<Triple> triplesObj1 = new HashSet<Triple>() ; // The triples of such a thing.
+
+ Set<Node> rejects = recordObjectMisses ? new HashSet<Node>() : null ; // Nodes known not to meet the requirement.
+
+ 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(graph, obj) ;
+ if ( n != null )
+ {
+ bNodesObj1.add(n) ;
+ // find triples to skip.
+ accTriplesOfSubject(triplesObj1, graph, obj) ;
+ }
+ }
+ iter.close() ;
+ return Pair.create(bNodesObj1, triplesObj1) ;
+ }
+
+ // CALCULATE FOR LISTS
+
+ static Transform<Triple, Node> subjects = new Transform<Triple, Node>() {
+
+ @Override
+ public Node convert(Triple item)
+ {
+ return item.getSubject() ;
+ }} ;
+
+ // Combine into a single pass.
+ // DISTINCT means it's space using.
+ static Iterator<Node> subjects(Graph graph)
+ {
+ // Later:
+ ExtendedIterator<Triple> iter = graph.find(Node.ANY, Node.ANY, Node.ANY) ;
+ return Iter.iter(iter).map(subjects).distinct() ;
+ }
+
+ 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)
+ {
+ Collection<Triple> x = new HashSet<Triple>() ;
+ accTriplesOfSubject(x, graph, subj) ;
+ return x ;
+ }
+
+ static void accTriplesOfSubject(Collection<Triple> acc, Graph graph, Node subj)
+ {
+ ExtendedIterator<Triple> iter = graph.find(subj, Node.ANY, Node.ANY) ;
+ for ( ; iter.hasNext() ; )
+ acc.add(iter.next()) ;
+ iter.close() ;
+ }
+}
+
Added: incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TriGWriter.java
URL: http://svn.apache.org/viewvc/incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TriGWriter.java?rev=1224807&view=auto
==============================================================================
--- incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TriGWriter.java (added)
+++ incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TriGWriter.java Mon Dec 26 20:57:13 2011
@@ -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 riot;
+
+import java.io.FileInputStream ;
+import java.io.FileNotFoundException ;
+import java.io.OutputStream ;
+import java.util.Iterator ;
+import java.util.Map ;
+
+import org.openjena.atlas.io.IndentedWriter ;
+import org.openjena.atlas.lib.Sink ;
+import org.openjena.riot.Lang ;
+import org.openjena.riot.RiotReader ;
+import org.openjena.riot.lang.SinkQuadsToDataset ;
+import org.openjena.riot.tokens.Tokenizer ;
+import org.openjena.riot.tokens.TokenizerFactory ;
+
+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.query.DatasetFactory ;
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.core.DatasetGraphFactory ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+
+public class TriGWriter
+{
+ public static void main(String ... argv) throws FileNotFoundException
+ {
+ DatasetGraph dsg = DatasetGraphFactory.createMem() ;
+
+ Tokenizer tokenizer = TokenizerFactory.makeTokenizerUTF8(new FileInputStream("D.trig")) ;
+
+ Sink<Quad> sink = new SinkQuadsToDataset(dsg) ;
+ RiotReader.createParserQuads(tokenizer, Lang.TRIG, null, sink).parse() ;
+ sink.flush() ;
+ write(System.out, DatasetFactory.create(dsg)) ;
+ }
+
+ 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() ;
+
+ }
+
+ public static void writeGraph(IndentedWriter out, Node name, Graph graph, Map<String, String> prefixMap)
+ {
+ if ( name != null )
+ {
+ TurtleWriter2.writeNode(out, name, prefixMap) ;
+ out.print(" ") ;
+ }
+ out.println("{") ;
+ out.incIndent(GRAPH_INDENT) ;
+ TurtleWriter2.write(out, graph, prefixMap) ;
+
+ out.decIndent(GRAPH_INDENT) ;
+ out.ensureStartOfLine() ;
+ out.println("}") ;
+ }
+
+}
+
Added: incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriter2.java
URL: http://svn.apache.org/viewvc/incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriter2.java?rev=1224807&view=auto
==============================================================================
--- incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriter2.java (added)
+++ incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriter2.java Mon Dec 26 20:57:13 2011
@@ -0,0 +1,392 @@
+/**
+ * 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.ByteArrayInputStream ;
+import java.io.ByteArrayOutputStream ;
+import java.io.OutputStream ;
+import java.util.* ;
+import java.util.Map.Entry ;
+
+import org.openjena.atlas.io.IndentedWriter ;
+import org.openjena.atlas.lib.Pair ;
+import org.openjena.atlas.lib.StrUtils ;
+import org.openjena.riot.SysRIOT ;
+
+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.rdf.model.Model ;
+import com.hp.hpl.jena.rdf.model.ModelFactory ;
+import com.hp.hpl.jena.sparql.util.FmtUtils ;
+import com.hp.hpl.jena.util.FileManager ;
+import com.hp.hpl.jena.vocabulary.RDF ;
+
+public class TurtleWriter2
+{
+ public static void main(String ... args)
+ {
+ SysRIOT.wireIntoJena() ;
+ Model m = FileManager.get().loadModel("D.ttl") ;
+
+ write(System.out, m) ;
+ System.out.println("----------------------------------") ;
+
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream() ;
+ write(out, m) ;
+ 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") ;
+
+ m.write(System.out, "TTL") ;
+
+ }
+
+ // TODO
+ // Order subjects to write
+ // ==> scan by subject, not triples
+
+ // Single pass analysis
+
+ // Lists
+ // Do before embeddable objects because list take precedence.
+
+ // Subjects \ one-connected objects
+
+ // 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.
+ // use object lists
+ // Configuration.
+
+ // Check old code for special cases.
+ // Use better output(Node) code.
+
+ // Check legality of prefix names generated.
+ // use stream node output (??)
+
+ // Generally, all padding should level dependent.
+
+ // Width of property before wrapping.
+ // This is not necessarily a control of total width
+ // e.g. the pretty writer may be writing properties inside indented one ref bNodes
+// protected int widePropertyLen = getIntValue("widePropertyLen", 20) ;
+//
+// // Column for property when an object follows a property on the same line
+// protected int propertyCol = getIntValue("propertyColumn", 8) ;
+//
+// // Minimum gap from property to object when object on a new line.
+// protected int indentObject = propertyCol ;
+//
+// // If a subject is shorter than this, the first property may go on same line.
+// protected int subjectColumn = getIntValue("subjectColumn", indentProperty) ;
+// // Require shortSubject < subjectCol (strict less than)
+
+
+
+ // TODO For TriG all these are relative.
+ private static final int LONG_SUBJECT = 20 ;
+ private static final int LONG_PREDICATE = 40 ; // Inc subject lentgh
+ private static final int PREFIX_IRI = 15;
+
+ // Column widths.
+ private static int COLW_SUBJECT = 6 ;
+ private static int COLW_PREDICATE = 8 ;
+
+
+ // Column for start of predicate
+ private static final int INDENT_PREDICATE = 8 ;
+
+ // Column for start of object
+ // Usually this is exceeded and predicate, objects are print with min gap.
+ private static final int INDENT_OBJECT = 8 ;
+
+
+ private static final String iriType = RDF.type.getURI() ;
+
+ private static final int MIN_GAP = 2 ;
+
+ private static final String rdfNS = RDF.getURI() ;
+
+ // Prepare prefixes.
+ // Need fast String=>prefix.
+
+ public static void write(OutputStream out, Model model)
+ {
+ write(out, model.getGraph(), model.getNsPrefixMap()) ;
+ }
+
+ public static void write(OutputStream out, Graph graph, Map<String, String> prefixMap)
+ {
+ IndentedWriter iOut = new IndentedWriter(out, false) ;
+ write(iOut, graph, prefixMap) ;
+ }
+
+ // Call from TriG as well.
+ static void write(IndentedWriter out, Graph graph, Map<String, String> prefixMap)
+ {
+ // Configuration.
+ Pair<Set<Node>, Set<Triple>> p = TW2.findOneConnectedBNodeObjects(graph) ;
+ Set<Node> bNodesObj1 = p.getLeft() ;
+ Set<Triple> triplesObj1 = p.getRight() ;
+
+ // Lists
+ writePrefixes(out, prefixMap) ;
+
+ // Or - listSubjects and sort.
+ Iterator<Node> subjects = TW2.subjects(graph) ;
+ writeBySubject(out, graph, subjects, bNodesObj1, triplesObj1, new HashSet<Object>(), prefixMap) ;
+ out.flush() ;
+ }
+
+ static void writePrefixes(IndentedWriter out, Map<String, String> prefixMap)
+ {
+ if ( ! prefixMap.isEmpty() )
+ {
+ // prepare?
+ for ( Map.Entry <String, String> e : prefixMap.entrySet() )
+ {
+ print(out, "@prefix ") ;
+ print(out, e.getKey()) ;
+ print(out, ": ") ;
+ pad(out, PREFIX_IRI) ;
+ print(out, "<") ;
+ print(out, e.getValue()) ; // Check?
+ print(out, ">") ;
+ print(out, " .") ;
+ println(out) ;
+ }
+ // Blank line.
+ println(out) ;
+ }
+ }
+
+ static void writeBySubject(IndentedWriter out, Graph graph,
+ Iterator<Node> subjects,
+ Collection<Node> nestedObjects, Collection<Triple> skip,
+ Collection<Object> lists,
+ Map<String, String> prefixMap)
+ {
+ for ( ; subjects.hasNext() ; )
+ {
+ Node subj = subjects.next() ;
+ if ( nestedObjects.contains(subj) )
+ continue ;
+
+ Collection<Triple> cluster = TW2.triplesOfSubject(graph, subj) ;
+ writeCluster(out, graph, subj, cluster, nestedObjects, prefixMap) ;
+ }
+ }
+
+
+ // Common subject
+ // Used by the blocks writer as well.
+ static void writeCluster(IndentedWriter out, Graph graph, Node subject, Collection<Triple> cluster,
+ Collection<Node> nestedObjects, Map<String, String> prefixMap)
+ {
+ //int OFFSET = out.getIndent() ;
+
+ if ( cluster.isEmpty() ) return ;
+ writeNode(out, subject, prefixMap) ;
+
+ if ( out.getCol() > LONG_SUBJECT )
+ println(out) ;
+ else
+ gap(out) ;
+ out.incIndent(INDENT_PREDICATE) ;
+ out.pad() ;
+ writePredicateObjectList(out, graph, cluster, nestedObjects, prefixMap) ;
+ out.decIndent(INDENT_PREDICATE) ;
+ print(out, " .") ; // Not perfect
+ println(out) ;
+ println(out) ;
+ }
+
+ // need to skip the triples nested.
+
+ private static void writePredicateObjectList(IndentedWriter out, Graph graph, Collection<Triple> cluster,
+ Collection<Node> nestedObjects, Map<String, String> prefixMap)
+ {
+ boolean first = true ;
+ // Calc columns
+
+ // Sort triples.
+ // rdf:type
+ // other rdf and rdfs
+ // properties together
+ // object lists?
+ // Find the colject pad column.
+
+
+ for ( Triple triple : cluster )
+ {
+ if ( first )
+ first = false ;
+ else
+ {
+ print(out, " ;") ;
+ println(out) ;
+ }
+
+ // Write predicate.
+ int colPredicateStart = out.getCol() ;
+
+ if ( ! prefixMap.containsValue(rdfNS) &&
+ triple.getPredicate().getURI().equals(iriType) )
+ // I prefer rdf:type when available.
+ print(out, "a") ;
+ else
+ writeNode(out, triple.getPredicate(), prefixMap) ;
+ int colPredicateFinish = out.getCol() ;
+ int wPredicate = (colPredicateFinish-colPredicateStart) ;
+
+ // Needs to be relative?
+ if ( wPredicate > LONG_PREDICATE )
+ out.println() ;
+ else
+ gap(out) ;
+
+ // Secondary one should be less
+ out.incIndent(INDENT_OBJECT) ;
+ out.pad() ;
+ Node obj = triple.getObject() ;
+ if ( nestedObjects.contains(obj) )
+ nestedObject(out, graph, obj, nestedObjects, prefixMap) ;
+ else
+ writeNode(out, triple.getObject(), prefixMap) ;
+ out.decIndent(INDENT_OBJECT) ;
+ }
+ }
+
+ private static void nestedObject(IndentedWriter out, Graph graph, Node obj,
+ Collection<Node> nestedObjects, Map<String, String> prefixMap)
+ {
+ Collection<Triple> x = TW2.triplesOfSubject(graph, obj) ;
+
+ if ( x.isEmpty() )
+ {
+ print(out, "[] ") ;
+ return ;
+ }
+
+ if ( x.size() == 1 )
+ {
+ print(out, "[ ") ;
+ // Includes nested object in triple.
+ writePredicateObjectList(out, graph, x, nestedObjects, prefixMap) ;
+ print(out, " ]") ;
+ return ;
+ }
+
+ // Two or more.
+ int here = out.getCol() ; // before "["
+ print(out, "[") ;
+ int i1 = out.getIndent() ;
+ out.setAbsoluteIndent(here) ;
+ // Inline: println(out) ;
+ out.incIndent(2) ;
+ writePredicateObjectList(out, graph, x, nestedObjects, prefixMap) ;
+ out.decIndent(2) ;
+ if ( true )
+ {
+ println(out) ; // Newline for "]"
+ print(out, "]") ;
+ }
+ else
+ { // Compact
+ print(out, " ]") ;
+ }
+ out.setAbsoluteIndent(i1) ;
+ }
+
+ static void writeNode(IndentedWriter out, Node node, Map<String, String> prefixMap)
+ {
+ // See RIOT NodeFormatter
+ if ( node.isURI() )
+ {
+ String iri = node.getURI() ;
+ // Crude.
+ String x = abbreviate(iri, prefixMap) ;
+ if ( x != null )
+ {
+ print(out, x) ;
+ return ;
+ }
+ }
+
+ print(out, 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 ;
+ }
+
+ private static boolean strSafeFor(String str, char ch) { return str.indexOf(ch) == -1 ; }
+
+ // flush aggressively (debugging)
+
+ private static void flush(IndentedWriter out) { out.flush() ; }
+
+ private static void print(IndentedWriter out, String string)
+ {
+ out.print(string) ;
+ flush(out) ;
+ }
+
+ private static void gap(IndentedWriter out)
+ {
+ out.print(' ', MIN_GAP) ;
+ }
+
+ private static void pad(IndentedWriter out, int col)
+ {
+ out.pad(col, true) ;
+ }
+
+ private static void println(IndentedWriter out)
+ {
+ out.println() ;
+ flush(out) ;
+ //System.err.println(out.getIndent()) ;
+ }
+
+
+}
+
Added: incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriterBlocks.java
URL: http://svn.apache.org/viewvc/incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriterBlocks.java?rev=1224807&view=auto
==============================================================================
--- incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriterBlocks.java (added)
+++ incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriterBlocks.java Mon Dec 26 20:57:13 2011
@@ -0,0 +1,101 @@
+/**
+ * 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 java.util.* ;
+
+import org.openjena.atlas.io.IndentedWriter ;
+import org.openjena.atlas.iterator.PeekIterator ;
+
+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.rdf.model.Model ;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator ;
+
+public class TurtleWriterBlocks
+{
+ public static void write(OutputStream out, Model model)
+ {
+ write(out, model.getGraph(), model.getNsPrefixMap()) ;
+ }
+
+ public static void write(OutputStream out, Graph graph, Map<String, String> prefixMap)
+ {
+ IndentedWriter iOut = new IndentedWriter(out, false) ;
+ write(iOut, graph, prefixMap) ;
+ }
+
+ static void write(IndentedWriter out, Graph graph, Map<String, String> prefixMap)
+ {
+ // Lists
+ TurtleWriter2.writePrefixes(out, prefixMap) ;
+ writeTriples(out, graph, graph.find(Node.ANY, Node.ANY, Node.ANY), prefixMap) ;
+ }
+
+
+ // Top level writer.
+ // Write blocks of same-subject triples, skipping anything we are going to process specially inline.
+ // If the collections are empty, this is about as good as streaming writing gets for Turtle.
+
+ // Change this to be a pure streaming, nested writer.
+ static void writeTriples(IndentedWriter out, Graph graph,
+ ExtendedIterator<Triple> triples,
+ Map<String, String> prefixMap)
+ {
+ Collection<Node> nestedObjects = Collections.emptyList() ;
+ Collection<Triple> skip = Collections.emptyList() ;
+ Collection<Object> lists = Collections.emptyList() ;
+
+ PeekIterator<Triple> stream = PeekIterator.create(triples) ;
+ List<Triple> cluster = new ArrayList<Triple>() ;
+ Node subject = null ;
+ for ( ; ; )
+ {
+ cluster.clear() ;
+ for ( ; stream.hasNext() ; )
+ {
+ Triple t = stream.peek() ;
+ if ( skip != null && skip.contains(t) )
+ {
+ stream.next() ;
+ continue ;
+ }
+
+ if ( subject == null )
+ subject = t.getSubject() ;
+ else if ( ! subject.equals(t.getSubject()) )
+ break ;
+ cluster.add(t) ;
+ stream.next() ;
+ }
+ if ( subject != null )
+ {
+ TurtleWriter2.writeCluster(out, graph, subject, cluster, nestedObjects, prefixMap) ;
+ subject = null ;
+ }
+ else
+ break ;
+ }
+ triples.close() ;
+ }
+
+}
+
Added: incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriterFlat.java
URL: http://svn.apache.org/viewvc/incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriterFlat.java?rev=1224807&view=auto
==============================================================================
--- incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriterFlat.java (added)
+++ incubator/jena/Scratch/AFS/Dev/trunk/src/main/java/riot/TurtleWriterFlat.java Mon Dec 26 20:57:13 2011
@@ -0,0 +1,58 @@
+/**
+ * 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.util.Iterator ;
+
+import org.openjena.atlas.io.IndentedWriter ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.Triple ;
+
+/** Write Turtle as one line of prefixed names */
+public class TurtleWriterFlat
+{
+ static public final int colWidth = 8 ;
+ static public final int predCol = 8 ;
+ static public final int objCol = 8+predCol ;
+
+ public static void write(IndentedWriter out, Graph graph)
+ {
+ Iterator<Triple> iter = graph.find(Node.ANY, Node.ANY, Node.ANY) ;
+
+ for ( ; iter.hasNext() ; )
+ {
+ Triple triple = iter.next() ;
+
+ triple.getSubject() ;
+ out.pad(predCol-1) ;
+ out.print(" ") ;
+
+
+ triple.getPredicate() ;
+ out.pad(objCol-1) ;
+ out.print(" ") ;
+
+ triple.getObject() ;
+
+ out.println(" .") ;
+ }
+ }
+}