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 2015/12/22 18:34:49 UTC

[3/4] jena git commit: JENA-1098: Code multiline literals (not enabled in this commit)

JENA-1098: Code multiline literals (not enabled in this commit)


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/8feb15e6
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/8feb15e6
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/8feb15e6

Branch: refs/heads/master
Commit: 8feb15e6afd6aaeb7d80c44af35ed3de1e469346
Parents: 72bcb91
Author: Andy Seaborne <an...@apache.org>
Authored: Sun Dec 20 17:36:19 2015 +0000
Committer: Andy Seaborne <an...@apache.org>
Committed: Tue Dec 22 17:32:00 2015 +0000

----------------------------------------------------------------------
 .../riot/out/NodeFormatterTTL_MultiLine.java    | 117 +++++++++++++++++++
 .../apache/jena/riot/writer/TurtleShell.java    |  28 ++++-
 2 files changed, 140 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/8feb15e6/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFormatterTTL_MultiLine.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFormatterTTL_MultiLine.java b/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFormatterTTL_MultiLine.java
new file mode 100644
index 0000000..5ee826c
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFormatterTTL_MultiLine.java
@@ -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 org.apache.jena.riot.out;
+
+import static org.apache.jena.atlas.lib.Chars.CH_QUOTE1 ;
+import static org.apache.jena.atlas.lib.Chars.CH_QUOTE2 ;
+
+import org.apache.jena.atlas.io.AWriter ;
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.riot.out.NodeFormatter ;
+import org.apache.jena.riot.out.NodeFormatterTTL ;
+import org.apache.jena.riot.out.quoted.QuotedStringOutput ;
+import org.apache.jena.riot.out.quoted.QuotedStringOutputTTL_MultiLine ;
+import org.apache.jena.riot.system.PrefixMap ;
+
+/** 
+ * Node formatter for pretty-printed Turtle.
+ *  This {@link NodeFormatter} switches between " and ' quotes to avoid ecapes.
+ *  This code writes multiline literals with """ or '''. 
+ */
+public class NodeFormatterTTL_MultiLine extends NodeFormatterTTL {
+    /// For '-quoted and "-quoted literals 
+    private final QuotedStringOutput escapeProc2 = new QuotedStringOutputTTL_MultiLine(CH_QUOTE2) ;
+    private final QuotedStringOutput escapeProc1 = new QuotedStringOutputTTL_MultiLine(CH_QUOTE1) ;
+
+    private boolean writeAsMultiLine(AWriter w, String lex) {
+        return ( lex.contains("\n") ) ;
+    }
+
+    public NodeFormatterTTL_MultiLine(String baseIRI, PrefixMap prefixMap) {
+        super(baseIRI, prefixMap) ;
+    }
+
+    public NodeFormatterTTL_MultiLine(String baseIRI, PrefixMap prefixMap, NodeToLabel nodeToLabel) {
+        super(baseIRI, prefixMap, nodeToLabel);
+    }
+
+    private Runnable noop = ()->{} ;
+
+    @Override
+    public void formatLitString(AWriter w, String lex)
+    {
+        if ( ! writeAsMultiLine(w, lex) ) {
+            writeLexicalSingleLine(w, lex, noop);
+            return ;
+        }
+        writeLexicalMultiLine(w, lex, noop) ; 
+    }
+
+    // To do ....
+    @Override
+    public void formatLitLang(AWriter w, String lex, String langTag) {
+        if ( ! writeAsMultiLine(w, lex) ) {
+            super.formatLitLang(w, lex, langTag);
+            return ;
+        }
+        writeLexicalMultiLine(w, lex, ()->{ w.print('@') ; w.print(langTag) ; }) ;
+    }
+
+    @Override
+    protected void writeLiteralLongForm(AWriter w, String lex, String datatypeURI)
+    {
+        if ( ! writeAsMultiLine(w, lex) ) {
+            super.writeLiteralOneLine(w, lex, datatypeURI);
+            return ;
+        }
+        writeLexicalMultiLine(w, lex, ()-> { w.print("^^") ; formatURI(w, datatypeURI) ; }) ;
+    }
+
+    private QuotedStringOutput chooseEscapeProcessor(String str) {
+        QuotedStringOutput proc = escapeProc2 ;
+        if ( str.indexOf(CH_QUOTE2) >= 0 && str.indexOf(CH_QUOTE1) < 0 )
+            // Contains " but not ' so print using '-quotes.   
+            proc = escapeProc1 ;
+        return proc ;
+    }
+
+    /** Output a string and run the Runnable at the same indentation level */ 
+    private void writeLexicalSingleLine(AWriter writer, String str, Runnable action) {
+        QuotedStringOutput proc = chooseEscapeProcessor(str) ;
+        proc.writeStr(writer, str); 
+    }
+
+    /** Output a string and run the Runnable at the same indentation level */ 
+    private void writeLexicalMultiLine(AWriter writer, String str, Runnable action) {
+        QuotedStringOutput escapeProc = chooseEscapeProcessor(str) ;
+        int indent = -1 ; 
+        IndentedWriter iw = null ;
+        if ( writer instanceof IndentedWriter ) {
+            iw = (IndentedWriter)writer ;
+            indent = iw.getAbsoluteIndent() ;
+            iw.setAbsoluteIndent(0);
+        }
+        escapeProc.writeStrMultiLine(writer, str) ;
+
+        if ( action != null )
+            action.run();
+        if ( indent >= 0 )
+            iw.setAbsoluteIndent(indent);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/8feb15e6/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java b/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java
index b7ea21c..bfc10ff 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/writer/TurtleShell.java
@@ -46,6 +46,7 @@ import org.apache.jena.graph.Triple ;
 import org.apache.jena.riot.other.GLib ;
 import org.apache.jena.riot.out.NodeFormatter ;
 import org.apache.jena.riot.out.NodeFormatterTTL ;
+import org.apache.jena.riot.out.NodeFormatterTTL_MultiLine ;
 import org.apache.jena.riot.out.NodeToLabel ;
 import org.apache.jena.riot.system.PrefixMap ;
 import org.apache.jena.riot.system.PrefixMapFactory ;
@@ -60,6 +61,8 @@ import org.apache.jena.vocabulary.RDFS ;
  * Base class to support the pretty forms of Turtle-related languages (Turtle, TriG)
  */
 public abstract class TurtleShell {
+    public static boolean enableMultiLine = false ; 
+    
     protected final IndentedWriter out ;
     protected final NodeFormatter  nodeFmt ;
     protected final PrefixMap      prefixMap ;
@@ -69,7 +72,11 @@ public abstract class TurtleShell {
         this.out = out ;
         if ( pmap == null )
             pmap = PrefixMapFactory.emptyPrefixMap() ;
-        this.nodeFmt = new NodeFormatterTTL(baseURI, pmap, NodeToLabel.createScopeByDocument()) ;
+        if ( ! enableMultiLine )
+            this.nodeFmt = new NodeFormatterTTL(baseURI, pmap, NodeToLabel.createScopeByDocument()) ;
+        else
+            // JENA-1098 - Work-in-progress.
+            this.nodeFmt = new NodeFormatterTTL_MultiLine(baseURI, pmap, NodeToLabel.createScopeByDocument()) ;
         this.prefixMap = pmap ;
         this.baseURI = baseURI ;
     }
@@ -652,11 +659,11 @@ public abstract class TurtleShell {
                     rdfSimpleNodes.add(o) ;
                 }
 
-                if ( rdfLiterals.size() != 0 ) {
+                if ( ! rdfLiterals.isEmpty() ) {
                     writePredicateObjectList(p, rdfLiterals, predicateMaxWidth, first) ;
                     first = false ;
                 }
-                if ( rdfSimpleNodes.size() != 0 ) {
+                if ( ! rdfSimpleNodes.isEmpty() ) {
                     writePredicateObjectList(p, rdfSimpleNodes, predicateMaxWidth, first) ;
                     first = false ;
                 }
@@ -678,13 +685,24 @@ public abstract class TurtleShell {
         private void writePredicateObjectList(Node p, List<Node> objects, int predicateMaxWidth, boolean first) {
             writePredicate(p, predicateMaxWidth, first) ;
             out.incIndent(INDENT_OBJECT) ;
+            
+            boolean lastObjectMultiLine = false ;
             boolean firstObject = true ;
             for ( Node o : objects ) {
-                if ( !firstObject )
-                    out.print(" , ") ;
+                if ( !firstObject ) {
+                    if ( out.getCurrentOffset() > 0 )
+                        out.print(" , ") ;
+                    else
+                        // Before the current indent, due to a multiline literal being written raw.
+                        // We will pad spaces to indent on output spaces.  Don't add a first " " 
+                        out.print(", ") ;
+                }
                 else
                     firstObject = false ;
+                int row1 = out.getRow() ;
                 writeNode(o) ;
+                int row2 = out.getRow();
+                lastObjectMultiLine = (row2 > row1) ;
             }
             out.decIndent(INDENT_OBJECT) ;
         }