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 2017/06/20 10:44:21 UTC
[1/6] jena git commit: General tidying up.
Repository: jena
Updated Branches:
refs/heads/master 887def848 -> f89025a83
General tidying up.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/bb7af3b4
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/bb7af3b4
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/bb7af3b4
Branch: refs/heads/master
Commit: bb7af3b4d1a7a11c1b48a31917d17c96d1291109
Parents: fbd93e3
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Jun 17 15:41:23 2017 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Jun 17 15:41:23 2017 +0100
----------------------------------------------------------------------
.../org/apache/jena/riot/system/RiotLib.java | 2 +-
.../apache/jena/riot/writer/TurtleShell.java | 2 +-
.../apache/jena/sparql/util/graph/Findable.java | 19 +++++-
.../sparql/util/graph/FindableCollection.java | 68 ++++++++++++++++++++
.../apache/jena/sparql/util/graph/GNode.java | 8 ++-
5 files changed, 94 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/bb7af3b4/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java b/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
index e06300e..637a640 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
@@ -101,7 +101,7 @@ public class RiotLib
return fixupPrefixIRI(prefix+":"+localPart);
}
- /** Convert an prefix name (qname) to an IRI, for when the prerix is nor defined.
+ /** Convert an prefix name (qname) to an IRI, for when the prefix is not defined.
* @see ARQ#fixupUndefinedPrefixes
*/
public static String fixupPrefixIRI(String prefixedName) {
http://git-wip-us.apache.org/repos/asf/jena/blob/bb7af3b4/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 a40cf6d..c820bb8 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
@@ -121,7 +121,7 @@ public abstract class TurtleShell {
private final Set<Node> freeBnodes ;
// The head node in each well-formed list -> list elements
- private /*final*/ Map<Node, List<Node>> lists ;
+ private final Map<Node, List<Node>> lists ;
// List that do not have any incoming triples
private final Map<Node, List<Node>> freeLists ;
http://git-wip-us.apache.org/repos/asf/jena/blob/bb7af3b4/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/Findable.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/Findable.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/Findable.java
index 95c9435..08275fa 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/Findable.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/Findable.java
@@ -20,11 +20,26 @@ package org.apache.jena.sparql.util.graph;
import java.util.Iterator ;
+import org.apache.jena.atlas.iterator.Iter;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.Triple ;
+/** Minimal interface to find by pattern */
public interface Findable
{
- public Iterator<Triple> find(Node s, Node p, Node o) ;
- public boolean contains(Node s, Node p, Node o) ;
+ /** Return an iterator over all triples matching the {@code (s,p,o)} pattern.
+ * Each element of {@code (s,p,o)} can be concrete, or the wildcard {@code Node.ANY}.
+ */
+ public Iterator<Triple> find(Node s, Node p, Node o) ;
+
+ /** Return whether any triple matches the (s,p,o) pattern.
+ * Each element of {@code (s,p,o)} can be concrete, or the wildcard {@code Node.ANY}.
+ */
+ public boolean contains(Node s, Node p, Node o) ;
+
+ /** Return the number of triples matching the (s,p,o) pattern.
+ */
+ public default int count(Node s, Node p, Node o) {
+ return (int)Iter.count(find(s,p,o));
+ }
}
http://git-wip-us.apache.org/repos/asf/jena/blob/bb7af3b4/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/FindableCollection.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/FindableCollection.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/FindableCollection.java
new file mode 100644
index 0000000..2a85439
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/FindableCollection.java
@@ -0,0 +1,68 @@
+/*
+ * 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.sparql.util.graph;
+
+import java.util.*;
+
+import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Triple ;
+
+public class FindableCollection implements Findable
+{
+ private Collection<Triple> triples ;
+
+ public FindableCollection(Collection<Triple> triples) { this.triples = triples ; }
+
+ @Override
+ public Iterator<Triple> find(Node _s, Node _p, Node _o) {
+ Node s = m(_s) ;
+ Node p = m(_p) ;
+ Node o = m(_o) ;
+ return Iter.filter(triples.iterator(), (t)->matches(t, s, p, o));
+ }
+
+ static Node m(Node n) {
+ return n == Node.ANY ? null : n ;
+ }
+
+ // Does concrete t match the pattern (s,p,o)?
+ /*package*/ static boolean matches(Triple t, Node s, Node p, Node o) {
+ if ( s != null && ! Objects.equals(s, t.getSubject()) )
+ return false ;
+ if ( p != null && ! Objects.equals(p, t.getPredicate()) )
+ return false ;
+ if ( o != null && ! Objects.equals(o, t.getObject()) )
+ return false ;
+ return true ;
+ }
+
+ @Override
+ public boolean contains(Node s, Node p, Node o)
+ {
+ if ( s == Node.ANY ) s = null ;
+ if ( p == Node.ANY ) p = null ;
+ if ( o == Node.ANY ) o = null ;
+ for ( Triple t : triples ) {
+ if ( matches(t, s, p, o) )
+ return true;
+ }
+ return false ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/bb7af3b4/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GNode.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GNode.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GNode.java
index d278d47..983f0cd 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GNode.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GNode.java
@@ -18,8 +18,11 @@
package org.apache.jena.sparql.util.graph;
+import java.util.Collection;
+
import org.apache.jena.graph.Graph ;
import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Triple;
import org.apache.jena.sparql.core.BasicPattern ;
@@ -32,8 +35,11 @@ public class GNode
{ this.findable = new FindableGraph(graph) ; this.node = node ; }
public GNode(BasicPattern triples, Node node)
- { this.findable = new FindableBasicPattern(triples) ; this.node = node ; }
+ { this.findable = new FindableCollection(triples.getList()) ; this.node = node ; }
+ public GNode(Collection<Triple> triples, Node node)
+ { this.findable = new FindableCollection(triples) ; this.node = node ; }
+
public GNode(GNode other, Node node)
{ this.findable = other.findable ; this.node = node ; }
[3/6] jena git commit: Support --fixup of prefix names.
Posted by an...@apache.org.
Support --fixup of prefix names.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/78217659
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/78217659
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/78217659
Branch: refs/heads/master
Commit: 78217659c3a4185a06cc0ef69b3ef6093fcb6c0d
Parents: d377dd1
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Jun 17 15:45:20 2017 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Jun 17 15:45:20 2017 +0100
----------------------------------------------------------------------
jena-cmds/src/main/java/arq/uparse.java | 70 ++++++++++++++++++++++------
1 file changed, 57 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/78217659/jena-cmds/src/main/java/arq/uparse.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/uparse.java b/jena-cmds/src/main/java/arq/uparse.java
index 83d44cb..22290b5 100644
--- a/jena-cmds/src/main/java/arq/uparse.java
+++ b/jena-cmds/src/main/java/arq/uparse.java
@@ -21,25 +21,30 @@ package arq;
import java.io.IOException ;
import java.util.List ;
+import arq.cmdline.CmdARQ ;
import jena.cmd.ArgDecl;
import jena.cmd.CmdException;
-
import org.apache.jena.atlas.io.IndentedLineBuffer ;
import org.apache.jena.atlas.lib.Lib ;
+import org.apache.jena.atlas.logging.LogCtl ;
+import org.apache.jena.query.ARQ ;
+import org.apache.jena.query.QueryException ;
import org.apache.jena.query.QueryParseException ;
import org.apache.jena.query.Syntax ;
+import org.apache.jena.sparql.core.QueryCheckException ;
+import org.apache.jena.sparql.lang.ParserBase ;
import org.apache.jena.sparql.modify.request.UpdateWriter ;
import org.apache.jena.update.UpdateFactory ;
import org.apache.jena.update.UpdateRequest ;
import org.apache.jena.util.FileUtils ;
-import arq.cmdline.CmdARQ ;
-
public class uparse extends CmdARQ
{
protected static final ArgDecl fileArg = new ArgDecl(ArgDecl.HasValue, "file", "update") ;
protected static final ArgDecl syntaxArg = new ArgDecl(ArgDecl.HasValue, "syntax", "syn") ;
protected static final ArgDecl argDeclPrint = new ArgDecl(ArgDecl.HasValue, "print") ;
+ protected static final ArgDecl argDeclFixup = new ArgDecl(ArgDecl.NoValue, "fixup") ;
+
List<String> requestFiles = null ;
protected Syntax updateSyntax = null ;
private boolean printUpdate = false ;
@@ -54,6 +59,7 @@ public class uparse extends CmdARQ
super.add(fileArg, "--file=FILE", "Update commands to parse") ;
super.add(syntaxArg, "--syntax=name", "Update syntax") ;
super.add(argDeclPrint, "--print", "Print in various forms [update, none]") ;
+ super.add(argDeclFixup, "--fixup", "Convert undeclared prefix names to URIs") ;
}
@Override
@@ -63,6 +69,10 @@ public class uparse extends CmdARQ
super.processModulesAndArgs() ;
if ( super.cmdStrictMode )
updateSyntax = Syntax.syntaxSPARQL_11 ;
+
+ if ( contains(argDeclFixup) )
+ // Fixup undeclared prefix names.
+ ARQ.set(ARQ.fixupUndefinedPrefixes, true);
// Set syntax
if ( super.contains(syntaxArg) ) {
@@ -86,7 +96,6 @@ public class uparse extends CmdARQ
if ( !printUpdate && ! printNone )
printUpdate = true ;
-
}
@Override
@@ -156,24 +165,59 @@ public class uparse extends CmdARQ
if ( printNone )
return ;
- // And some checking.
+
+ try {
+ LogCtl.disable(ParserBase.ParserLoggerName) ;
+ checkUpdate(req, syntax);
+ } catch (UpdateCheckException ex)
+ {
+ System.err.println() ;
+ System.err.println("**** Check failure: "+ex.getMessage()) ;
+ if ( ex.getCause() != null )
+ ex.getCause().printStackTrace(System.err) ;
+ }
+ finally { LogCtl.setLevel(ParserBase.ParserLoggerName, "INFO") ; }
+ }
+
+ public static class UpdateCheckException extends QueryException
+ {
+ public UpdateCheckException() { super() ; }
+ public UpdateCheckException(Throwable cause) { super(cause) ; }
+ public UpdateCheckException(String msg) { super(msg) ; }
+ public UpdateCheckException(String msg, Throwable cause) { super(msg, cause) ; }
+ }
+
+
+ public static void checkUpdate(UpdateRequest req, Syntax syntax)
+ {
IndentedLineBuffer w = new IndentedLineBuffer() ;
UpdateWriter.output(req, w) ;
String updateString2 = w.asString() ;
- UpdateRequest req2 = null ;
+
+ UpdateRequest req2;
try {
+ String baseURI = null ;
+ if ( ! req.explicitlySetBaseURI() )
+ baseURI = req.getBaseURI() ;
req2 = UpdateFactory.create(updateString2, syntax) ;
- } catch (QueryParseException ex)
+ } catch (UnsupportedOperationException ex)
{
- System.err.println("Can not reparse update after serialization") ;
- System.err.println(updateString2) ;
+ // No parser after all.
+ return ;
+ }
+ catch (QueryException ex)
+ {
+ System.err.println(updateString2) ;
+ throw new QueryCheckException("could not parse output update request", ex) ;
}
-
- if ( ! req.equalTo(req2) )
- System.err.println("Reparsed update does not .equalTo original parsed request") ;
-
+// if ( req.hashCode() != req2.hashCode() )
+// throw new UpdateCheckException("reparsed query hashCode does not equal parsed input update \nUpdate (hashCode: " + req.hashCode() + ")=\n" + req + "\n\nUpdate2 (hashCode: " + req2.hashCode() + ")=\n" + req2) ;
+//
+// if ( ! req.equals(req2) )
+// throw new UpdateCheckException("reparsed output does not equal parsed input") ;
}
+
static final String divider = "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" ;
//static final String divider = "" ;
[6/6] jena git commit: JENA-1361,
JENA-369: Merge commit 'refs/pull/263/head' of github.com:apache/jena
Posted by an...@apache.org.
JENA-1361, JENA-369: Merge commit 'refs/pull/263/head' of github.com:apache/jena
This closes #263.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/f89025a8
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/f89025a8
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/f89025a8
Branch: refs/heads/master
Commit: f89025a832aa8f854f0cee012be560b550c11ffd
Parents: 887def8 f19d8b2
Author: Andy Seaborne <an...@apache.org>
Authored: Tue Jun 20 11:42:47 2017 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Tue Jun 20 11:42:47 2017 +0100
----------------------------------------------------------------------
.../org/apache/jena/riot/system/RiotLib.java | 2 +-
.../apache/jena/riot/writer/TurtleShell.java | 2 +-
.../sparql/modify/request/UpdateWriter.java | 2 +
.../modify/request/UpdateWriterVisitor.java | 10 +-
.../jena/sparql/serializer/FmtEltLib.java | 195 ++++++
.../sparql/serializer/FormatterElement.java | 688 ++++++++++---------
.../sparql/serializer/TriplesListBlock.java | 43 ++
.../apache/jena/sparql/util/graph/Findable.java | 19 +-
.../sparql/util/graph/FindableBasicPattern.java | 89 ---
.../sparql/util/graph/FindableCollection.java | 68 ++
.../apache/jena/sparql/util/graph/GNode.java | 8 +-
jena-cmds/src/main/java/arq/uparse.java | 70 +-
12 files changed, 771 insertions(+), 425 deletions(-)
----------------------------------------------------------------------
[4/6] jena git commit: Tidy up.
Posted by an...@apache.org.
Tidy up.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/9a3a072e
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/9a3a072e
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/9a3a072e
Branch: refs/heads/master
Commit: 9a3a072e14203e2a6712bfc2444cf94538f49e92
Parents: 7821765
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Jun 17 15:45:36 2017 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Jun 17 15:45:36 2017 +0100
----------------------------------------------------------------------
.../sparql/util/graph/FindableBasicPattern.java | 89 --------------------
1 file changed, 89 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/9a3a072e/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/FindableBasicPattern.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/FindableBasicPattern.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/FindableBasicPattern.java
deleted file mode 100644
index a421ca9..0000000
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/FindableBasicPattern.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.sparql.util.graph;
-
-import java.util.ArrayList ;
-import java.util.Iterator ;
-import java.util.List ;
-
-import org.apache.jena.graph.Node ;
-import org.apache.jena.graph.Triple ;
-import org.apache.jena.sparql.core.BasicPattern ;
-
-
-
-
-class FindableBasicPattern implements Findable
-{
- private BasicPattern triples ;
-
- FindableBasicPattern(BasicPattern triples) { this.triples = triples ; }
-
- @Override
- public Iterator<Triple> find(Node s, Node p, Node o)
- {
- if ( s == Node.ANY ) s = null ;
- if ( p == Node.ANY ) p = null ;
- if ( o == Node.ANY ) o = null ;
-
- List<Triple> r = new ArrayList<>() ;
- for ( Triple t : triples )
- {
- if ( s != null && !t.getSubject().equals( s ) )
- {
- continue;
- }
- if ( p != null && !t.getPredicate().equals( p ) )
- {
- continue;
- }
- if ( o != null && !t.getObject().equals( o ) )
- {
- continue;
- }
- r.add( t );
- }
- return r.iterator() ;
- }
-
- @Override
- public boolean contains(Node s, Node p, Node o)
- {
- if ( s == Node.ANY ) s = null ;
- if ( p == Node.ANY ) p = null ;
- if ( o == Node.ANY ) o = null ;
- for ( Triple t : triples )
- {
- if ( s != null && !t.getSubject().equals( s ) )
- {
- continue;
- }
- if ( p != null && !t.getPredicate().equals( p ) )
- {
- continue;
- }
- if ( o != null && !t.getObject().equals( o ) )
- {
- continue;
- }
- return true;
- }
- return false ;
- }
-}
[5/6] jena git commit: JENA-369: Output pretty lists in basic graph
patterns.
Posted by an...@apache.org.
JENA-369: Output pretty lists in basic graph patterns.
This includes property functions.
Conversion is cautious - it looks for the triples as the parser
might output them.
Nested bnodes structures in lists are not converted back.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/f19d8b26
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/f19d8b26
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/f19d8b26
Branch: refs/heads/master
Commit: f19d8b267e1976f655e2c7509e6c7ce67c0c9496
Parents: 9a3a072
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Jun 17 15:48:12 2017 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sun Jun 18 09:26:55 2017 +0100
----------------------------------------------------------------------
.../jena/sparql/serializer/FmtEltLib.java | 195 ++++++
.../sparql/serializer/FormatterElement.java | 688 ++++++++++---------
.../sparql/serializer/TriplesListBlock.java | 43 ++
3 files changed, 612 insertions(+), 314 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/f19d8b26/jena-arq/src/main/java/org/apache/jena/sparql/serializer/FmtEltLib.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/serializer/FmtEltLib.java b/jena-arq/src/main/java/org/apache/jena/sparql/serializer/FmtEltLib.java
new file mode 100644
index 0000000..d14f3da
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/serializer/FmtEltLib.java
@@ -0,0 +1,195 @@
+/*
+ * 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.sparql.serializer;
+
+import static org.apache.jena.graph.Node.ANY;
+
+import java.util.*;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.sparql.core.BasicPattern;
+import org.apache.jena.vocabulary.RDF;
+
+/** Place to move some of the code from FormatterElement */
+class FmtEltLib {
+
+ /*package*/ static Node rdfFirst = RDF.Nodes.first;
+ /*package*/ static Node rdfRest = RDF.Nodes.rest;
+ /*package*/ static Node rdfNil = RDF.Nodes.nil;
+
+ // Cautious list finder.
+ // The list must be like the parser creates them:
+ // Adjacent triples, in first, rest order.
+
+ // It does support embedded lists.
+ // It does not support bnode structures i.e. [:prop :obj]
+
+ // Ths code simply finds lists - it does not perform checks as to their suitablity to print in ()-form.
+
+ /*package*/ static TriplesListBlock createTriplesListBlock(BasicPattern bgp) {
+ TriplesListBlock tlb = new TriplesListBlock();
+ List<Triple> triples = bgp.getList();
+ for ( int idx = 0 ; idx < triples.size() ; idx++ ) {
+ Triple t = triples.get(idx);
+ if ( idx == triples.size() - 1 )
+ // Can't be a following triple.
+ break;
+ // null -> ANY
+ if ( matches(t, ANY, rdfFirst, ANY) ) {
+ Node consCell = t.getSubject();
+ int numTriples = collectList(consCell, idx, triples, tlb);
+ if ( numTriples > 0 ) {
+ // Skip triples.
+ idx = idx + numTriples - 1 ;
+ } else {
+ // Play safe
+ // skip to (? rdf:rest rdf:nil) (if any).
+ for ( idx = idx + 1 ; idx < triples.size() ; idx++ ) {
+ Triple t2 = triples.get(idx);
+ if ( matches(t2, ANY, rdfRest, rdfNil) )
+ break;
+ }
+ }
+ }
+ }
+ return tlb;
+ }
+
+ private static Node nullAsAny(Node n) {
+ return n == null ? ANY : n ;
+ }
+
+ /*package*/ static boolean matches(Triple t, Node s, Node p, Node o) {
+ s = nullAsAny(s) ;
+ p = nullAsAny(p) ;
+ o = nullAsAny(o) ;
+ if ( s != ANY && ! Objects.equals(s, t.getSubject()) )
+ return false ;
+ if ( p != ANY && ! Objects.equals(p, t.getPredicate()) )
+ return false ;
+ if ( o != ANY && ! Objects.equals(o, t.getObject()) )
+ return false ;
+ return true ;
+ }
+
+ /*package*/ static int collectList(Node consCell, int idx, List<Triple> triples, TriplesListBlock tlb) {
+ Set<Triple> listTriples = new LinkedHashSet<>();
+ TriplesListBlock block1 = collectList1(consCell, idx, triples, listTriples, tlb);
+ if ( block1 == null )
+ // Failed.
+ return -1;
+ if ( ! FormatterElement.FMT_FREE_STANDING_LISTS ) {
+ // Reject free standiang lists.
+ int inCount = count(triples, ANY, ANY, consCell);
+ int outCount = count(triples, consCell, ANY, ANY);
+ if ( inCount == 0 && outCount == 2 )
+ return -1;
+ }
+
+ int numTriples = block1.triplesInLists.size();
+ tlb.merge(block1);
+ return numTriples;
+ }
+
+ /**
+ * Spot parser pattern of adjacent "first-rest" pairs.
+ * Collect elements of a well-formed list else null.
+ * {@code triplesInList}.
+ */
+ /*package*/ static TriplesListBlock collectList1(Node consCell, int idx, List<Triple> triples, Set<Triple> triplesInList, TriplesListBlock tlb) {
+ // This list - accumulate separately because we aren't sure it is well-formed yet.
+ TriplesListBlock thisList = new TriplesListBlock();
+ List<Node> elts = new ArrayList<>();
+ thisList.listElementsMap.put(consCell, elts);
+
+ for ( ;; ) {
+ if ( idx + 1 >= triples.size() )
+ // Last triple - can't be an rdf:first, rdf:rest pair.
+ return null;
+ Triple t1 = triples.get(idx);
+ consCell = t1.getSubject();
+
+ Triple t2 = triples.get(idx + 1);
+
+ // -- Checks on t1
+ // t1 : (consCell rdf:first element)
+ if ( ! matches(t1, consCell, rdfFirst, ANY) )
+ return null;
+
+ // ---- Possible compound value.
+ // Second triple is rdf:rest, or rdf:first for a list in a list.
+ // or arbitrary triples for [:p :q] in a list.
+ // We don't handle the latter case because programatic can make this anything.
+
+ final boolean ListsInLists = true ;
+ if ( ListsInLists ) {
+ if ( rdfFirst.equals(t2.getPredicate()) && t1.getObject().equals(t2.getSubject()) ) {
+ // Recursion.
+ int numProcessed = collectList(t2.getSubject(), idx + 1, triples, thisList); // -1
+ if ( numProcessed < 0 )
+ return null;
+ // Not "-1" - this loop does not have autoincrement.
+ idx = idx + numProcessed ;
+ // idx: Posn of the rdf:nil. Probe to see if t2 is an "rdf:rest" to consider.
+ t2 = triples.get(idx + 1);
+ }
+ }
+
+ // -- Checks on t2
+ // t2 : (consCell rdf:rest element)
+ if ( ! matches(t2, consCell, rdfRest, ANY) )
+ return null;
+ // -- Check consCell - no other triples or one if a subject list.
+ int outCount = count(triples, consCell, ANY, ANY) ;
+ if ( outCount != 2 ) {
+ // Head cell also be a subject list. in which case the first cell of the list can have a count of 3.
+ if ( outCount == 3 && ! elts.isEmpty() )
+ return null;
+ }
+
+
+ int inCount = count(triples, ANY, ANY, consCell) ;
+ if ( inCount != 1 ) {
+ // Head cell can also be zero : subject or free standing list head.
+ if ( outCount == 0 && ! elts.isEmpty() )
+ return null;
+ }
+
+
+ Node elt = t1.getObject();
+ thisList.triplesInLists.add(t1);
+ thisList.triplesInLists.add(t2);
+ elts.add(elt);
+ if ( matches(t2, ANY, ANY, rdfNil) ) {
+ return thisList;
+ }
+ idx += 2;
+ }
+ }
+
+ /*package*/ static int count(List<Triple> triples, Node s, Node p, Node o) {
+ int count = 0 ;
+ for ( Triple t : triples ) {
+ if ( matches(t, s, p, o) )
+ count++;
+ }
+ return count;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/f19d8b26/jena-arq/src/main/java/org/apache/jena/sparql/serializer/FormatterElement.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/serializer/FormatterElement.java b/jena-arq/src/main/java/org/apache/jena/sparql/serializer/FormatterElement.java
index 2d1f6cc..4770fce 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/serializer/FormatterElement.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/serializer/FormatterElement.java
@@ -1,5 +1,5 @@
/*
- * Licensed to the Apache Software Foundation (ASF) under one
+f * 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
@@ -18,283 +18,286 @@
package org.apache.jena.sparql.serializer;
-import java.util.ArrayList ;
-import java.util.Iterator ;
-import java.util.List ;
+import static org.apache.jena.graph.Node.ANY;
+import static org.apache.jena.sparql.serializer.FmtEltLib.count;
+import static org.apache.jena.sparql.serializer.FmtEltLib.createTriplesListBlock;
+import static org.apache.jena.sparql.serializer.FmtEltLib.rdfFirst;
-import org.apache.jena.atlas.io.IndentedLineBuffer ;
-import org.apache.jena.atlas.io.IndentedWriter ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.graph.Triple ;
-import org.apache.jena.query.Query ;
+import java.util.*;
+
+import org.apache.jena.atlas.io.IndentedLineBuffer;
+import org.apache.jena.atlas.io.IndentedWriter;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.query.Query;
import org.apache.jena.query.QueryVisitor;
import org.apache.jena.query.Syntax;
-import org.apache.jena.sparql.core.BasicPattern ;
-import org.apache.jena.sparql.core.PathBlock ;
-import org.apache.jena.sparql.core.TriplePath ;
-import org.apache.jena.sparql.expr.Expr ;
-import org.apache.jena.sparql.path.PathWriter ;
-import org.apache.jena.sparql.syntax.* ;
-import org.apache.jena.sparql.util.FmtUtils ;
-import org.apache.jena.vocabulary.RDF ;
-
-
-public class FormatterElement extends FormatterBase
- implements ElementVisitor
-{
- public static final int INDENT = 2 ;
-
+import org.apache.jena.sparql.core.BasicPattern;
+import org.apache.jena.sparql.core.PathBlock;
+import org.apache.jena.sparql.core.TriplePath;
+import org.apache.jena.sparql.expr.Expr;
+import org.apache.jena.sparql.path.PathWriter;
+import org.apache.jena.sparql.syntax.*;
+import org.apache.jena.sparql.util.FmtUtils;
+import org.apache.jena.vocabulary.RDF;
+
+public class FormatterElement extends FormatterBase implements ElementVisitor {
+ public static final int INDENT = 2;
+
/** Control whether to show triple pattern boundaries - creates extra nesting */
- public static final boolean PATTERN_MARKERS = false ;
-
-// /** Control whether triple patterns always have a final dot - it can be dropped in some cases */
-// public static boolean PATTERN_FINAL_DOT = false ;
+ public static final boolean PATTERN_MARKERS = false;
+
+// /** Control whether triple patterns always have a final dot - it can be dropped in some cases */
+// public static boolean PATTERN_FINAL_DOT = false ;
/** Control whether (non-triple) patterns have a final dot - it can be dropped */
- public static final boolean GROUP_SEP_DOT = false ;
-
+ public static final boolean GROUP_SEP_DOT = false;
+
/** Control whether the first item of a group is on the same line as the { */
- public static final boolean GROUP_FIRST_ON_SAME_LINE = true ;
+ public static final boolean GROUP_FIRST_ON_SAME_LINE = true;
/** Control pretty printing */
- public static final boolean PRETTY_PRINT = true ;
+ public static final boolean PRETTY_PRINT = true;
- /** Control whether disjunction has set of delimiters - as it's a group usually, these aren't needed */
- public static final boolean UNION_MARKERS = false ;
+ /** Control pretty printing of RDF lists */
+ public static final boolean FMT_LISTS = true;
+ /** Control pretty printing of free standing RDF lists */
+ // Do *not* set "true" - argument of property paths can be lists and these spane
+ // PathBlocks and Basic Graph Patterns and this is not handled prop.
+ public static final boolean FMT_FREE_STANDING_LISTS = false;
+
+ /**
+ * Control whether disjunction has set of delimiters - as it's a group usually, these
+ * aren't needed
+ */
+ public static final boolean UNION_MARKERS = false;
+
/** Control whether GRAPH indents in a fixed way or based on the layout size */
- public static final boolean GRAPH_FIXED_INDENT = true ;
-
- /** Control whether NOT EXIST/EXISTS indents in a fixed way or based on the layout size */
- public static final boolean ELEMENT1_FIXED_INDENT = true ;
-
+ public static final boolean GRAPH_FIXED_INDENT = true;
+
+ /**
+ * Control whether NOT EXIST/EXISTS indents in a fixed way or based on the layout size
+ */
+ public static final boolean ELEMENT1_FIXED_INDENT = true;
+
/** Control triples pretty printing */
- public static final int TRIPLES_SUBJECT_COLUMN = 8 ;
-
+ public static final int TRIPLES_SUBJECT_COLUMN = 8;
+
// Less than this => rest of triple on the same line
- // Could be smart and make it depend on the property length as well. Later.
- public static final int TRIPLES_SUBJECT_LONG = 12 ;
+ // Could be smart and make it depend on the property length as well. Later.
+ public static final int TRIPLES_SUBJECT_LONG = 12;
- public static final int TRIPLES_PROPERTY_COLUMN = 20;
-
- public static final int TRIPLES_COLUMN_GAP = 2 ;
+ public static final int TRIPLES_PROPERTY_COLUMN = 20;
+
+ public static final int TRIPLES_COLUMN_GAP = 2;
public FormatterElement(IndentedWriter out, SerializationContext context) {
- super(out, context) ;
+ super(out, context);
}
public static void format(IndentedWriter out, SerializationContext cxt, Element el) {
- FormatterElement fmt = new FormatterElement(out, cxt) ;
- fmt.startVisit() ;
- el.visit(fmt) ;
- fmt.finishVisit() ;
+ FormatterElement fmt = new FormatterElement(out, cxt);
+ fmt.startVisit();
+ el.visit(fmt);
+ fmt.finishVisit();
}
public static String asString(Element el) {
- SerializationContext cxt = new SerializationContext() ;
- IndentedLineBuffer b = new IndentedLineBuffer() ;
- FormatterElement.format(b, cxt, el) ;
- return b.toString() ;
+ SerializationContext cxt = new SerializationContext();
+ IndentedLineBuffer b = new IndentedLineBuffer();
+ FormatterElement.format(b, cxt, el);
+ return b.toString();
}
public boolean topMustBeGroup() {
- return false ;
+ return false;
}
@Override
public void visit(ElementTriplesBlock el) {
if ( el.isEmpty() ) {
- out.println("# Empty BGP") ;
- return ;
+ out.println("# Empty BGP");
+ return;
}
- formatTriples(el.getPattern()) ;
+ formatTriples(el.getPattern());
}
@Override
public void visit(ElementPathBlock el) {
- // Write path block - don't put in a final trailing "."
+ // Write path block - don't put in a final trailing "."
if ( el.isEmpty() ) {
- out.println("# Empty BGP") ;
- return ;
+ out.println("# Empty BGP");
+ return;
}
// Split into BGP-path-BGP-...
// where the BGPs may be empty.
- PathBlock pBlk = el.getPattern() ;
- BasicPattern bgp = new BasicPattern() ;
- boolean first = true ; // Has anything been output?
+ PathBlock pBlk = el.getPattern();
+ BasicPattern bgp = new BasicPattern();
+ boolean first = true; // Has anything been output?
for ( TriplePath tp : pBlk ) {
if ( tp.isTriple() ) {
- bgp.add(tp.asTriple()) ;
- continue ;
+ bgp.add(tp.asTriple());
+ continue;
}
-
+
if ( !bgp.isEmpty() ) {
if ( !first )
- out.println(" .") ;
- flush(bgp) ;
- first = false ;
+ out.println(" .");
+ flush(bgp);
+ first = false;
}
if ( !first )
- out.println(" .") ;
- // Path
- printSubject(tp.getSubject()) ;
- out.print(" ") ;
- PathWriter.write(out, tp.getPath(), context.getPrologue()) ;
- out.print(" ") ;
- printObject(tp.getObject()) ;
- first = false ;
+ out.println(" .");
+ // Path (no RDF list output).
+ printSubject(tp.getSubject());
+ out.print(" ");
+ PathWriter.write(out, tp.getPath(), context.getPrologue());
+ out.print(" ");
+ printObject(tp.getObject());
+ first = false;
}
// Flush any stored triple patterns.
if ( !bgp.isEmpty() ) {
if ( !first )
- out.println(" .") ;
- flush(bgp) ;
- first = false ;
+ out.println(" .");
+ flush(bgp);
+ first = false;
}
}
- private void flush(BasicPattern bgp) {
- formatTriples(bgp) ;
- bgp.getList().clear();
- }
-
@Override
- public void visit(ElementDataset el)
- {
-// if ( el.getDataset() != null)
-// {
-// DatasetGraph dsNamed = el.getDataset() ;
-// out.print("DATASET ") ;
-// out.incIndent(INDENT) ;
-// Iterator iter = dsNamed.listNames() ;
-// if ( iter.hasNext() )
-// {
-// boolean first = false ;
-// for ( ; iter.hasNext() ; )
-// {
-// if ( ! first )
-// out.newline() ;
-// out.print("FROM <") ;
-// String s = (String)iter.next() ;
-// out.print(s) ;
-// out.print(">") ;
+ public void visit(ElementDataset el) {
+ // Not implemented.
+// if ( el.getDataset() != null ) {
+// DatasetGraph dsNamed = el.getDataset();
+// out.print("DATASET ");
+// out.incIndent(INDENT);
+// Iterator<Node> iter = dsNamed.listGraphNodes();
+// if ( iter.hasNext() ) {
+// boolean first = false;
+// for ( ; iter.hasNext() ; ) {
+// if ( !first )
+// out.newline();
+// out.print("FROM <");
+// Node n = iter.next();
+// out.print(slotToString(n));
+// out.print(">");
// }
// }
-// out.decIndent(INDENT) ;
-// out.newline() ;
+// out.decIndent(INDENT);
+// out.newline();
// }
- if ( el.getElement() != null )
- visitAsGroup(el.getElement()) ;
+// if ( el.getElement() != null )
+// visitAsGroup(el.getElement());
}
@Override
public void visit(ElementFilter el) {
- out.print("FILTER ") ;
- Expr expr = el.getExpr() ;
- FmtExprSPARQL v = new FmtExprSPARQL(out, context) ;
+ out.print("FILTER ");
+ Expr expr = el.getExpr();
+ FmtExprSPARQL v = new FmtExprSPARQL(out, context);
// This assumes that complex expressions are bracketted
// (parens) as necessary except for some cases:
// Plain variable or constant
- boolean addParens = false ;
+ boolean addParens = false;
if ( expr.isVariable() )
- addParens = true ;
+ addParens = true;
if ( expr.isConstant() )
- addParens = true ;
+ addParens = true;
if ( addParens )
- out.print("( ") ;
- v.format(expr) ;
+ out.print("( ");
+ v.format(expr);
if ( addParens )
- out.print(" )") ;
+ out.print(" )");
}
@Override
public void visit(ElementAssign el) {
- out.print("LET (") ;
- out.print("?" + el.getVar().getVarName()) ;
- out.print(" := ") ;
- FmtExprSPARQL v = new FmtExprSPARQL(out, context) ;
- v.format(el.getExpr()) ;
- out.print(")") ;
+ out.print("LET (");
+ out.print("?" + el.getVar().getVarName());
+ out.print(" := ");
+ FmtExprSPARQL v = new FmtExprSPARQL(out, context);
+ v.format(el.getExpr());
+ out.print(")");
}
@Override
public void visit(ElementBind el) {
- out.print("BIND(") ;
- FmtExprSPARQL v = new FmtExprSPARQL(out, context) ;
- v.format(el.getExpr()) ;
- out.print(" AS ") ;
- out.print("?" + el.getVar().getVarName()) ;
- out.print(")") ;
+ out.print("BIND(");
+ FmtExprSPARQL v = new FmtExprSPARQL(out, context);
+ v.format(el.getExpr());
+ out.print(" AS ");
+ out.print("?" + el.getVar().getVarName());
+ out.print(")");
}
@Override
public void visit(ElementData el) {
- QuerySerializer.outputDataBlock(out, el.getVars(), el.getRows(), context) ;
+ QuerySerializer.outputDataBlock(out, el.getVars(), el.getRows(), context);
}
@Override
public void visit(ElementUnion el) {
if ( el.getElements().size() == 1 ) {
// If this is an element of just one, just do it inplace
- // Can't happen from a parsed query.
- // Now can :-)
-
- // SPARQL 1.1 inline UNION.
- // Same as OPTIONAL, MINUS
- out.print("UNION") ;
- out.incIndent(INDENT) ;
- out.newline() ;
- visitAsGroup(el.getElements().get(0)) ;
- out.decIndent(INDENT) ;
- return ;
+ // Can't happen from a parsed query in SPARQL.
+ visitAsGroup(el.getElements().get(0));
+// // Same as OPTIONAL, MINUS
+// out.print("UNION");
+// out.incIndent(INDENT);
+// out.newline();
+// visitAsGroup(el.getElements().get(0));
+// out.decIndent(INDENT);
+ return;
}
if ( UNION_MARKERS ) {
- out.print("{") ;
- out.newline() ;
- out.pad() ;
+ out.print("{");
+ out.newline();
+ out.pad();
}
- out.incIndent(INDENT) ;
+ out.incIndent(INDENT);
- boolean first = true ;
+ boolean first = true;
for ( Element subElement : el.getElements() ) {
if ( !first ) {
- out.decIndent(INDENT) ;
- out.newline() ;
- out.print("UNION") ;
- out.newline() ;
- out.incIndent(INDENT) ;
+ out.decIndent(INDENT);
+ out.newline();
+ out.print("UNION");
+ out.newline();
+ out.incIndent(INDENT);
}
- visitAsGroup(subElement) ;
- first = false ;
+ visitAsGroup(subElement);
+ first = false;
}
- out.decIndent(INDENT) ;
+ out.decIndent(INDENT);
if ( UNION_MARKERS ) {
- out.newline() ;
- out.print("}") ;
+ out.newline();
+ out.print("}");
}
}
@Override
public void visit(ElementGroup el) {
- out.print("{") ;
- int initialRowNumber = out.getRow() ;
- out.incIndent(INDENT) ;
+ out.print("{");
+ int initialRowNumber = out.getRow();
+ out.incIndent(INDENT);
if ( !GROUP_FIRST_ON_SAME_LINE )
- out.newline() ;
+ out.newline();
- int row1 = out.getRow() ;
- out.pad() ;
+ int row1 = out.getRow();
+ out.pad();
- boolean first = true ;
- Element lastElt = null ;
+ boolean first = true;
+ Element lastElt = null;
for ( Element subElement : el.getElements() ) {
// Some adjacent elements need a DOT:
@@ -303,302 +306,359 @@ public class FormatterElement extends FormatterBase
// Need to move on after the last thing printed.
// Check for necessary DOT as separator
if ( GROUP_SEP_DOT || needsDotSeparator(lastElt, subElement) )
- out.print(" . ") ;
- out.newline() ;
+ out.print(" . ");
+ out.newline();
}
- subElement.visit(this) ;
- first = false ;
- lastElt = subElement ;
+ subElement.visit(this);
+ first = false;
+ lastElt = subElement;
}
- out.decIndent(INDENT) ;
+ out.decIndent(INDENT);
// Where to put the closing "}"
- int row2 = out.getRow() ;
+ int row2 = out.getRow();
if ( row1 != row2 )
- out.newline() ;
+ out.newline();
// Finally, close the group.
if ( out.getRow() == initialRowNumber )
- out.print(" ") ;
- out.print("}") ;
+ out.print(" ");
+ out.print("}");
}
private static boolean needsDotSeparator(Element el1, Element el2) {
- return needsDotSeparator(el1) && needsDotSeparator(el2) ;
+ return needsDotSeparator(el1) && needsDotSeparator(el2);
}
private static boolean needsDotSeparator(Element el) {
- return (el instanceof ElementTriplesBlock) || (el instanceof ElementPathBlock) ;
+ return (el instanceof ElementTriplesBlock) || (el instanceof ElementPathBlock);
}
@Override
public void visit(ElementOptional el) {
- out.print("OPTIONAL") ;
- out.incIndent(INDENT) ;
- out.newline() ;
- visitAsGroup(el.getOptionalElement()) ;
- out.decIndent(INDENT) ;
+ out.print("OPTIONAL");
+ out.incIndent(INDENT);
+ out.newline();
+ visitAsGroup(el.getOptionalElement());
+ out.decIndent(INDENT);
}
@Override
public void visit(ElementNamedGraph el) {
- visitNodePattern("GRAPH", el.getGraphNameNode(), el.getElement()) ;
+ visitNodePattern("GRAPH", el.getGraphNameNode(), el.getElement());
}
@Override
public void visit(ElementService el) {
- String x = "SERVICE" ;
+ String x = "SERVICE";
if ( el.getSilent() )
- x = "SERVICE SILENT" ;
- visitNodePattern(x, el.getServiceNode(), el.getElement()) ;
+ x = "SERVICE SILENT";
+ visitNodePattern(x, el.getServiceNode(), el.getElement());
}
private void visitNodePattern(String label, Node node, Element subElement) {
- int len = label.length() ;
- out.print(label) ;
- out.print(" ") ;
- String nodeStr = (node == null) ? "*" : slotToString(node) ;
- out.print(nodeStr) ;
- len += nodeStr.length() ;
+ int len = label.length();
+ out.print(label);
+ out.print(" ");
+ String nodeStr = (node == null) ? "*" : slotToString(node);
+ out.print(nodeStr);
+ len += nodeStr.length();
if ( GRAPH_FIXED_INDENT ) {
- out.incIndent(INDENT) ;
- out.newline() ; // NB and newline
+ out.incIndent(INDENT);
+ out.newline(); // NB and newline
} else {
- out.print(" ") ;
- len++ ;
- out.incIndent(len) ;
+ out.print(" ");
+ len++;
+ out.incIndent(len);
}
- visitAsGroup(subElement) ;
+ visitAsGroup(subElement);
if ( GRAPH_FIXED_INDENT )
- out.decIndent(INDENT) ;
+ out.decIndent(INDENT);
else
- out.decIndent(len) ;
+ out.decIndent(len);
}
private void visitElement1(String label, Element1 el) {
- int len = label.length() ;
- out.print(label) ;
- len += label.length() ;
+ int len = label.length();
+ out.print(label);
+ len += label.length();
if ( ELEMENT1_FIXED_INDENT ) {
- out.incIndent(INDENT) ;
- out.newline() ; // NB and newline
+ out.incIndent(INDENT);
+ out.newline(); // NB and newline
} else {
- out.print(" ") ;
- len++ ;
- out.incIndent(len) ;
+ out.print(" ");
+ len++;
+ out.incIndent(len);
}
- visitAsGroup(el.getElement()) ;
+ visitAsGroup(el.getElement());
if ( ELEMENT1_FIXED_INDENT )
- out.decIndent(INDENT) ;
+ out.decIndent(INDENT);
else
- out.decIndent(len) ;
+ out.decIndent(len);
}
@Override
public void visit(ElementExists el) {
- visitElement1("EXISTS", el) ;
+ visitElement1("EXISTS", el);
}
@Override
public void visit(ElementNotExists el) {
- visitElement1("NOT EXISTS", el) ;
+ visitElement1("NOT EXISTS", el);
}
@Override
public void visit(ElementMinus el) {
- out.print("MINUS") ;
- out.incIndent(INDENT) ;
- out.newline() ;
- visitAsGroup(el.getMinusElement()) ;
- out.decIndent(INDENT) ;
+ out.print("MINUS");
+ out.incIndent(INDENT);
+ out.newline();
+ visitAsGroup(el.getMinusElement());
+ out.decIndent(INDENT);
}
@Override
public void visit(ElementSubQuery el) {
- out.print("{ ") ;
- out.incIndent(INDENT) ;
- Query q = el.getQuery() ;
+ out.print("{ ");
+ out.incIndent(INDENT);
+ Query q = el.getQuery();
// Serialize with respect to the existing context
- QuerySerializerFactory factory = SerializerRegistry.get().getQuerySerializerFactory(Syntax.syntaxARQ) ;
- QueryVisitor serializer = factory.create(Syntax.syntaxARQ, context, out) ;
- q.visit(serializer) ;
+ QuerySerializerFactory factory = SerializerRegistry.get().getQuerySerializerFactory(Syntax.syntaxARQ);
+ QueryVisitor serializer = factory.create(Syntax.syntaxARQ, context, out);
+ q.visit(serializer);
- out.decIndent(INDENT) ;
- out.print("}") ;
+ out.decIndent(INDENT);
+ out.print("}");
}
public void visitAsGroup(Element el) {
- boolean needBraces = !((el instanceof ElementGroup) || (el instanceof ElementSubQuery)) ;
+ boolean needBraces = !((el instanceof ElementGroup) || (el instanceof ElementSubQuery));
if ( needBraces ) {
- out.print("{ ") ;
- out.incIndent(INDENT) ;
+ out.print("{ ");
+ out.incIndent(INDENT);
}
- el.visit(this) ;
+ el.visit(this);
if ( needBraces ) {
- out.decIndent(INDENT) ;
- out.print("}") ;
+ out.decIndent(INDENT);
+ out.print("}");
}
}
-
- int subjectWidth = -1 ;
- int predicateWidth = -1 ;
+ // -------- Formatting a basic graph pattern
+ // Triple order is preserved.
+
+ int subjectWidth = -1;
+ int predicateWidth = -1;
+
@Override
protected void formatTriples(BasicPattern triples) {
if ( !PRETTY_PRINT ) {
- super.formatTriples(triples) ;
- return ;
+ super.formatTriples(triples);
+ return;
}
- // TODO RDF Collections - spot the parsers pattern
if ( triples.isEmpty() )
- return ;
+ return;
+
+ // Lists in this BasicPattern.
+ // TriplesListBlock is a record of lists in this BGP.
+ // Formatting is off for list if there is an empty TriplesListBlock.
+ // This is cautionsly spotting the triples from RDF lists as generated by the
+ // parser.
- setWidths(triples) ;
+ TriplesListBlock block = FMT_LISTS
+ ? createTriplesListBlock(triples)
+ : new TriplesListBlock();
+
+ Set<Node> freeStanding = new HashSet<>();
+ for ( Node head : block.listElementsMap.keySet() ) {
+ // Check for suitablity to print.
+ // See also FmtEltLib#collectList
+ //
+ // Subject-list : inCount = 0, outCount = 3
+ // Object-list : inCount = 1, outCount = 2
+ // Free-standing list : inCount = 0, outCount = 2
+ // Free-standing list is handled as a special case.
+ int inCount = count(triples.getList(), ANY, ANY, head);
+ int outCount = count(triples.getList(), head, ANY, ANY);
+ if ( inCount == 0 && outCount == 2 )
+ // Free standing.
+ freeStanding.add(head);
+ }
+
+ setWidths(triples);
if ( subjectWidth > TRIPLES_SUBJECT_COLUMN )
- subjectWidth = TRIPLES_SUBJECT_COLUMN ;
+ subjectWidth = TRIPLES_SUBJECT_COLUMN;
if ( predicateWidth > TRIPLES_PROPERTY_COLUMN )
- predicateWidth = TRIPLES_PROPERTY_COLUMN ;
+ predicateWidth = TRIPLES_PROPERTY_COLUMN;
- // Loops:
- List<Triple> subjAcc = new ArrayList<>() ; // Accumulate all triples
- // with the same subject.
- Node subj = null ; // Subject being accumulated
+ // Accumulate all triples with the same subject.
+ List<Triple> subjAcc = new ArrayList<>();
+ // Subject being accumulated
+ Node subj = null;
+ // Print newlines between blocks.
+ boolean first = true;
- boolean first = true ; // Print newlines between blocks.
-
- int indent = -1 ;
+ int indent = -1;
for ( Triple t : triples ) {
+ if ( block.triplesInLists.contains(t) ) {
+ if ( rdfFirst.equals(t.getPredicate()) ) {
+ if ( freeStanding.contains(t.getSubject()) )
+ printNodeOrList(t.getSubject(), block.listElementsMap);
+ }
+ continue;
+ }
+
if ( subj != null && t.getSubject().equals(subj) ) {
- subjAcc.add(t) ;
- continue ;
+ subjAcc.add(t);
+ continue;
}
if ( subj != null ) {
if ( !first )
- out.println(" .") ;
- formatSameSubject(subj, subjAcc) ;
- first = false ;
+ out.println(" .");
+ formatSameSubject(subj, subjAcc, block.listElementsMap);
+ first = false;
// At end of line of a block of triples with same subject.
// Drop through and start new block of same subject triples.
}
// New subject
- subj = t.getSubject() ;
- subjAcc.clear() ;
- subjAcc.add(t) ;
+ subj = t.getSubject();
+ subjAcc.clear();
+ subjAcc.add(t);
}
// Flush accumulator
if ( subj != null && subjAcc.size() != 0 ) {
if ( !first )
- out.println(" .") ;
- first = false ;
- formatSameSubject(subj, subjAcc) ;
+ out.println(" .");
+ first = false;
+ formatSameSubject(subj, subjAcc, block.listElementsMap);
}
}
- private void formatSameSubject(Node subject, List<Triple> triples) {
+ // ----
+
+ private void flush(BasicPattern bgp) {
+ formatTriples(bgp);
+ bgp.getList().clear();
+ }
+
+ private void formatSameSubject(Node subject, List<Triple> triples, Map<Node, List<Node>> lists) {
+
if ( triples == null || triples.size() == 0 )
- return ;
-
- // Do the first triple.
- Iterator<Triple> iter = triples.iterator() ;
- Triple t1 = iter.next() ;
+ return;
-// int indent = TRIPLES_SUBJECT_COLUMN+TRIPLES_COLUMN_GAP ;
-// // Long subject => same line. Works for single triple as well.
-// int s1_len = printSubject(t1.getSubject()) ;
-// //int x = out.getCol() ;
+ // Do the first triple.
+ Iterator<Triple> iter = triples.iterator();
+ Triple t1 = iter.next();
- int indent = subjectWidth + TRIPLES_COLUMN_GAP ;
- int s1_len = printSubject(t1.getSubject()) ;
+ int indent = subjectWidth + TRIPLES_COLUMN_GAP;
+ int s1_len = printNodeOrList(subject, lists);
if ( s1_len > TRIPLES_SUBJECT_LONG ) {
- // Too long - start a new line.
- out.incIndent(indent) ;
- out.println() ;
+ out.incIndent(indent);
+ out.println();
} else {
- printGap() ;
- out.incIndent(indent) ;
+ printGap();
+ out.incIndent(indent);
}
// Remainder of first triple
- printProperty(t1.getPredicate()) ;
- printGap() ;
- printObject(t1.getObject()) ;
+ printProperty(t1.getPredicate());
+ printGap();
- // Do the rest
+ printNodeOrList(t1.getObject(), lists);
+ // Do the rest
for ( ; iter.hasNext() ; ) {
- Triple t = iter.next() ;
- out.println(" ;") ;
- printProperty(t.getPredicate()) ;
- printGap() ;
- printObject(t.getObject()) ;
- continue ;
- // print property list
+ Triple t = iter.next();
+ out.println(" ;");
+ printProperty(t.getPredicate());
+ printGap();
+ printNodeOrList(t.getObject(), lists);
+ continue;
}
// Finish off the block.
- out.decIndent(indent) ;
+ out.decIndent(indent);
// out.print(" .") ;
}
+ private int printNodeOrList(Node node, Map<Node, List<Node>> lists) {
+ if ( lists.containsKey(node) )
+ return printList(lists.get(node), lists);
+ else
+ return printNoCol(node);
+ }
+
private void setWidths(BasicPattern triples) {
- subjectWidth = -1 ;
- predicateWidth = -1 ;
+ subjectWidth = -1;
+ predicateWidth = -1;
for ( Triple t : triples ) {
- String s = slotToString(t.getSubject()) ;
+ String s = slotToString(t.getSubject());
if ( s.length() > subjectWidth )
- subjectWidth = s.length() ;
+ subjectWidth = s.length();
- String p = slotToString(t.getPredicate()) ;
+ String p = slotToString(t.getPredicate());
if ( p.length() > predicateWidth )
- predicateWidth = p.length() ;
+ predicateWidth = p.length();
}
}
private void printGap() {
- out.print(' ', TRIPLES_COLUMN_GAP) ;
+ out.print(' ', TRIPLES_COLUMN_GAP);
}
- // Indent must be set first.
+ // printSubject, printObject - used in ElementPathBlock.
private int printSubject(Node s) {
- String str = slotToString(s) ;
- out.print(str) ;
- out.pad(subjectWidth) ;
- return str.length() ;
+ return printNoCol(s);
}
// Assumes the indent is TRIPLES_SUBJECT_COLUMN+GAP
- private static String RDFTYPE = FmtUtils.stringForNode(RDF.Nodes.type, new SerializationContext()) ;
-
+ private static String RDFTYPE = FmtUtils.stringForNode(RDF.Nodes.type, new SerializationContext());
+
private int printProperty(Node p) {
- String str = slotToString(p) ;
+ String str = slotToString(p);
if ( p.equals(RDF.Nodes.type) && str.equals(RDFTYPE) )
- out.print("a") ;
+ out.print("a");
else
- out.print(str) ;
- out.pad(predicateWidth) ;
- return str.length() ;
+ out.print(str);
+ out.pad(predicateWidth);
+ return str.length();
}
private int printObject(Node obj) {
- return printNoCol(obj) ;
+ return printNoCol(obj);
}
- private int printNoCol(Node node) {
- String str = slotToString(node) ;
- out.print(str) ;
- return str.length() ;
+ private int printList(List<Node> list, Map<Node, List<Node>> lists) {
+ if ( list.isEmpty() ) {
+ out.print("()");
+ return 2;
+ }
+
+ int col0 = out.getCol();
+ out.print("( ");
+ for ( Node n : list ) {
+ printNodeOrList(n, lists);
+ out.print(" ");
+ }
+ out.print(")");
+ int col1 = out.getCol();
+ return col1 - col0;
+ }
+ private int printNoCol(Node node) {
+ String str = slotToString(node);
+ out.print(str);
+ return str.length();
}
}
http://git-wip-us.apache.org/repos/asf/jena/blob/f19d8b26/jena-arq/src/main/java/org/apache/jena/sparql/serializer/TriplesListBlock.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/serializer/TriplesListBlock.java b/jena-arq/src/main/java/org/apache/jena/sparql/serializer/TriplesListBlock.java
new file mode 100644
index 0000000..37671b8
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/serializer/TriplesListBlock.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.sparql.serializer;
+
+import java.util.*;
+
+import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+
+/** Internal record of list details. */
+/*package*/ class TriplesListBlock {
+ Map<Node, List<Node>> listElementsMap = new HashMap<>();
+ // Triples in lists.
+ Set<Triple> triplesInLists = new LinkedHashSet<>();
+
+ /*package*/ void merge(TriplesListBlock other) {
+ listElementsMap.putAll(other.listElementsMap);
+ triplesInLists.addAll(other.triplesInLists);
+ }
+
+ @Override
+ public String toString() {
+ return Iter.asString(listElementsMap.keySet(), ", ") + "\n" + "{"+ Iter.asString(triplesInLists.iterator(), "\n")+"}";
+
+ }
+}
\ No newline at end of file
[2/6] jena git commit: JENA-1361: Convert back to blank nodes.
Posted by an...@apache.org.
JENA-1361: Convert back to blank nodes.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/d377dd14
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/d377dd14
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/d377dd14
Branch: refs/heads/master
Commit: d377dd141028ae81ed373b86d3fc8f26cc898447
Parents: bb7af3b
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Jun 17 15:44:48 2017 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Jun 17 15:44:48 2017 +0100
----------------------------------------------------------------------
.../apache/jena/sparql/modify/request/UpdateWriter.java | 2 ++
.../jena/sparql/modify/request/UpdateWriterVisitor.java | 10 ++++++----
2 files changed, 8 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/d377dd14/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriter.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriter.java b/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriter.java
index c2a2e35..1f79f55 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriter.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriter.java
@@ -54,6 +54,8 @@ public class UpdateWriter implements UpdateSerializer
// To get legal syntax out, the serialization context
// has to be a bNode mapping that does ??N vars to bNodes
if (sCxt == null)
+ // This is the one used for INSERT and DELETE templates.
+ // For the WHERE clause, see UpdateWriterVisitor.prepareElementFormatter
sCxt = new SerializationContext((Prologue)null, new NodeToLabelMapBNode());
this.out = out;
http://git-wip-us.apache.org/repos/asf/jena/blob/d377dd14/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriterVisitor.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriterVisitor.java b/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriterVisitor.java
index e8a19ec..7672f71 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriterVisitor.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateWriterVisitor.java
@@ -32,6 +32,7 @@ import org.apache.jena.sparql.serializer.FormatterElement ;
import org.apache.jena.sparql.serializer.SerializationContext ;
import org.apache.jena.sparql.syntax.Element ;
import org.apache.jena.sparql.util.FmtUtils ;
+import org.apache.jena.sparql.util.NodeToLabelMapBNode ;
public class UpdateWriterVisitor implements UpdateVisitor
{
@@ -212,7 +213,6 @@ public class UpdateWriterVisitor implements UpdateVisitor
String $ = FmtUtils.stringForNode(node, sCxt) ;
out.print($) ;
}
-
@Override
public void visit(UpdateDeleteWhere update)
@@ -233,7 +233,6 @@ public class UpdateWriterVisitor implements UpdateVisitor
output(update.getWithIRI()) ;
}
-
if ( update.hasDeleteClause() )
{
List<Quad> deleteQuads = update.getDeleteQuads() ;
@@ -242,7 +241,6 @@ public class UpdateWriterVisitor implements UpdateVisitor
outputQuadsBraced(deleteQuads) ;
}
-
if ( update.hasInsertClause() )
{
List<Quad> insertQuads = update.getInsertQuads() ;
@@ -272,6 +270,7 @@ public class UpdateWriterVisitor implements UpdateVisitor
output(x) ;
}
+ // Wrong.
Element el = update.getWherePattern() ;
out.ensureStartOfLine() ;
out.print("WHERE") ;
@@ -289,6 +288,9 @@ public class UpdateWriterVisitor implements UpdateVisitor
}
protected FormatterElement prepareElementFormatter() {
- return new FormatterElement(out, sCxt);
+ SerializationContext sCxt1 = new SerializationContext(sCxt);
+ // The label prefix is different to the template writer just for clarity.
+ sCxt1.setBNodeMap(new NodeToLabelMapBNode("x", false));
+ return new FormatterElement(out, sCxt1);
}
}
\ No newline at end of file