You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by cl...@apache.org on 2023/11/27 16:03:17 UTC
(jena) branch main updated: JENA-2357 Added Collection and collection SPARQL textual representation as a valid argument to the QueryBuilder clauses.
This is an automated email from the ASF dual-hosted git repository.
claude pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git
The following commit(s) were added to refs/heads/main by this push:
new 5d5beb64d6 JENA-2357 Added Collection and collection SPARQL textual representation as a valid argument to the QueryBuilder clauses.
new a3165eb4f7 Merge pull request #2085 from Claudenw/add_list_to_builder_where
5d5beb64d6 is described below
commit 5d5beb64d619eb0108293261b6fdebfd34f269cf
Author: Claude Warren <cl...@xenei.com>
AuthorDate: Mon Nov 27 17:00:36 2023 +0100
JENA-2357 Added Collection and collection SPARQL textual representation as a valid argument to the QueryBuilder clauses.
---
.../arq/querybuilder/AbstractQueryBuilder.java | 32 ++
.../apache/jena/arq/querybuilder/AskBuilder.java | 38 +-
.../jena/arq/querybuilder/ConstructBuilder.java | 45 ++-
.../apache/jena/arq/querybuilder/Converters.java | 386 ++++++++++++++++++++-
.../jena/arq/querybuilder/DescribeBuilder.java | 43 ++-
.../jena/arq/querybuilder/SelectBuilder.java | 46 ++-
.../jena/arq/querybuilder/UpdateBuilder.java | 102 +++++-
.../apache/jena/arq/querybuilder/WhereBuilder.java | 41 ++-
.../jena/arq/querybuilder/clauses/WhereClause.java | 30 +-
.../arq/querybuilder/handlers/WhereHandler.java | 51 ++-
.../querybuilder/rewriters/AbstractRewriter.java | 6 +-
.../updatebuilder/WhereQuadHolder.java | 28 ++
.../apache/jena/arq/TestAbstractQueryBuilder.java | 37 ++
.../arq/querybuilder/AbstractQueryBuilderTest.java | 44 ++-
.../jena/arq/querybuilder/AskBuilderTest.java | 1 +
.../arq/querybuilder/ConstructBuilderTest.java | 1 +
.../jena/arq/querybuilder/ConvertersTest.java | 125 ++++++-
.../jena/arq/querybuilder/SelectBuilderTest.java | 16 +-
.../querybuilder/clauses/SolutionModifierTest.java | 11 +-
.../arq/querybuilder/clauses/WhereClauseTest.java | 179 +++++++++-
.../handlers/SolutionModifierHandlerTest.java | 11 +-
.../querybuilder/handlers/WhereHandlerTest.java | 103 ++++--
22 files changed, 1233 insertions(+), 143 deletions(-)
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilder.java
index d1c5bcb9a0..53f48d1cc5 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilder.java
@@ -146,7 +146,9 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>>
* @param p the predicate object
* @param o the object object.
* @return a TriplePath
+ * @deprecated Use {@link makeTriplePaths(Object, Object, Object)}
*/
+ @Deprecated(since="5.0.0")
public TriplePath makeTriplePath(Object s, Object p, Object o) {
final Object po = makeNodeOrPath(p);
if (po instanceof Path) {
@@ -154,6 +156,36 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>>
}
return new TriplePath(Triple.create(makeNode(s), (Node) po, makeNode(o)));
}
+
+ /**
+ * Make a collecton triple path from the objects.
+ *
+ * For subject, predicate and objects nodes
+ * <ul>
+ * <li>Will return Node.ANY if object is null.</li>
+ * <li>Will return the enclosed Node from a FrontsNode</li>
+ * <li>Will return the object if it is a Node.</li>
+ * <li>For {@code subject} and {@code object} <em>only</em>, if the object is a collection, will convert each item
+ * in the collection into a node and create an RDF list. All RDF list nodes are included in the collection.</li>
+ * <li>If the object is a String
+ * <ul>
+ * <li>For <code>predicate</code> <em>only</em>, will attempt to parse as a path</li>
+ * <li>for subject, predicate and object will call NodeFactoryExtra.parseNode()
+ * using the currently defined prefixes if the object is a String</li>
+ * </ul>
+ * </li>
+ * <li>Will create a literal representation if the parseNode() fails or for any
+ * other object type.</li>
+ * </ul>
+ *
+ * @param s The subject object
+ * @param p the predicate object
+ * @param o the object object.
+ * @return a TriplePath
+ */
+ public List<TriplePath> makeTriplePaths(Object s, Object p, Object o) {
+ return Converters.makeTriplePaths(s, p, o, query.getPrefixMapping());
+ }
/**
* A convenience method to make an expression from a string. Evaluates the
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AskBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AskBuilder.java
index 21033a94a0..4fce3786e3 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AskBuilder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AskBuilder.java
@@ -113,6 +113,12 @@ public class AskBuilder extends AbstractQueryBuilder<AskBuilder>
return this;
}
+ @Override
+ public AskBuilder addWhere(Collection<TriplePath> collection) {
+ getWhereHandler().addWhere(collection);
+ return this;
+ }
+
@Override
public AskBuilder addWhere(Triple t) {
getWhereHandler().addWhere(new TriplePath(t));
@@ -127,7 +133,7 @@ public class AskBuilder extends AbstractQueryBuilder<AskBuilder>
@Override
public AskBuilder addWhere(Object s, Object p, Object o) {
- getWhereHandler().addWhere(makeTriplePath(s, p, o));
+ getWhereHandler().addWhere(makeTriplePaths(s, p, o));
return this;
}
@@ -185,8 +191,7 @@ public class AskBuilder extends AbstractQueryBuilder<AskBuilder>
@Override
public AskBuilder addOptional(Triple t) {
- getWhereHandler().addOptional(new TriplePath(t));
- return this;
+ return addOptional(new TriplePath(t));
}
@Override
@@ -196,14 +201,19 @@ public class AskBuilder extends AbstractQueryBuilder<AskBuilder>
}
@Override
- public AskBuilder addOptional(FrontsTriple t) {
- getWhereHandler().addOptional(new TriplePath(t.asTriple()));
+ public AskBuilder addOptional(Collection<TriplePath> collection) {
+ getWhereHandler().addOptional(collection);
return this;
}
+ @Override
+ public AskBuilder addOptional(FrontsTriple t) {
+ return addOptional(new TriplePath(t.asTriple()));
+ }
+
@Override
public AskBuilder addOptional(Object s, Object p, Object o) {
- getWhereHandler().addOptional(makeTriplePath(s, p, o));
+ getWhereHandler().addOptional(makeTriplePaths(s, p, o));
return this;
}
@@ -240,19 +250,19 @@ public class AskBuilder extends AbstractQueryBuilder<AskBuilder>
@Override
public AskBuilder addGraph(Object graph, FrontsTriple triple) {
- getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple.asTriple()));
+ addGraph(graph, new TriplePath(triple.asTriple()));
return this;
}
@Override
public AskBuilder addGraph(Object graph, Object subject, Object predicate, Object object) {
- getWhereHandler().addGraph(makeNode(graph), makeTriplePath(subject, predicate, object));
+ getWhereHandler().addGraph(makeNode(graph), makeTriplePaths(subject, predicate, object));
return this;
}
@Override
public AskBuilder addGraph(Object graph, Triple triple) {
- getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple));
+ addGraph(graph, new TriplePath(triple));
return this;
}
@@ -262,6 +272,12 @@ public class AskBuilder extends AbstractQueryBuilder<AskBuilder>
return this;
}
+ @Override
+ public AskBuilder addGraph(Object graph, Collection<TriplePath> collection) {
+ getWhereHandler().addGraph(makeNode(graph), collection);
+ return this;
+ }
+
@Override
public AskBuilder addBind(Expr expression, Object var) {
getWhereHandler().addBind(expression, Converters.makeVar(var));
@@ -363,6 +379,10 @@ public class AskBuilder extends AbstractQueryBuilder<AskBuilder>
return handlerBlock.getModifierHandler();
}
+ /*
+ * @deprecated use {@code addWhere(Converters.makeCollection(List.of(Object...)))}, or simply call {@link #addWhere(Object, Object, Object)} passing the collection for one of the objects.
+ */
+ @Deprecated(since="5.0.0")
@Override
public Node list(Object... objs) {
return getWhereHandler().list(objs);
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ConstructBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ConstructBuilder.java
index 669d527172..3a9b30dd5c 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ConstructBuilder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ConstructBuilder.java
@@ -17,6 +17,7 @@
*/
package org.apache.jena.arq.querybuilder;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -210,6 +211,12 @@ public class ConstructBuilder extends AbstractQueryBuilder<ConstructBuilder> imp
return this;
}
+ @Override
+ public ConstructBuilder addWhere(Collection<TriplePath> collection) {
+ getWhereHandler().addWhere(collection);
+ return this;
+ }
+
@Override
public ConstructBuilder addWhere(Triple t) {
getWhereHandler().addWhere(new TriplePath(t));
@@ -224,7 +231,7 @@ public class ConstructBuilder extends AbstractQueryBuilder<ConstructBuilder> imp
@Override
public ConstructBuilder addWhere(Object s, Object p, Object o) {
- getWhereHandler().addWhere(makeTriplePath(s, p, o));
+ getWhereHandler().addWhere(makeTriplePaths(s, p, o));
return this;
}
@@ -276,15 +283,20 @@ public class ConstructBuilder extends AbstractQueryBuilder<ConstructBuilder> imp
@Override
public ConstructBuilder addOptional(TriplePath t) {
- getWhereHandler().addOptional(t);
+ getWhereHandler().addOptional(Arrays.asList(t));
return this;
}
@Override
- public ConstructBuilder addOptional(Triple t) {
- getWhereHandler().addOptional(new TriplePath(t));
+ public ConstructBuilder addOptional(Collection<TriplePath> collection) {
+ getWhereHandler().addOptional(collection);
return this;
}
+
+ @Override
+ public ConstructBuilder addOptional(Triple t) {
+ return addOptional(new TriplePath(t));
+ }
@Override
public ConstructBuilder addOptional(AbstractQueryBuilder<?> t) {
@@ -294,13 +306,12 @@ public class ConstructBuilder extends AbstractQueryBuilder<ConstructBuilder> imp
@Override
public ConstructBuilder addOptional(FrontsTriple t) {
- getWhereHandler().addOptional(new TriplePath(t.asTriple()));
- return this;
+ return addOptional(new TriplePath(t.asTriple()));
}
@Override
public ConstructBuilder addOptional(Object s, Object p, Object o) {
- getWhereHandler().addOptional(makeTriplePath(s, p, o));
+ getWhereHandler().addOptional(makeTriplePaths(s, p, o));
return this;
}
@@ -337,25 +348,29 @@ public class ConstructBuilder extends AbstractQueryBuilder<ConstructBuilder> imp
@Override
public ConstructBuilder addGraph(Object graph, FrontsTriple triple) {
- getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple.asTriple()));
- return this;
+ return addGraph(graph, new TriplePath(triple.asTriple()));
}
@Override
public ConstructBuilder addGraph(Object graph, Object subject, Object predicate, Object object) {
- getWhereHandler().addGraph(makeNode(graph), makeTriplePath(subject, predicate, object));
+ getWhereHandler().addGraph(makeNode(graph), makeTriplePaths(subject, predicate, object));
return this;
}
@Override
public ConstructBuilder addGraph(Object graph, Triple triple) {
- getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple));
- return this;
+ return addGraph(graph, new TriplePath(triple));
}
@Override
public ConstructBuilder addGraph(Object graph, TriplePath triplePath) {
- getWhereHandler().addGraph(makeNode(graph), triplePath);
+ getWhereHandler().addGraph(makeNode(graph), Arrays.asList(triplePath));
+ return this;
+ }
+
+ @Override
+ public ConstructBuilder addGraph(Object graph, Collection<TriplePath> collection) {
+ getWhereHandler().addGraph(makeNode(graph), collection);
return this;
}
@@ -387,6 +402,10 @@ public class ConstructBuilder extends AbstractQueryBuilder<ConstructBuilder> imp
return addConstruct(Triple.create(makeNode(s), makeNode(p), makeNode(o)));
}
+ /*
+ * @deprecated use {@code addWhere(Converters.makeCollection(List.of(Object...)))}, or simply call {@link #addWhere(Object, Object, Object)} passing the collection for one of the objects.
+ */
+ @Deprecated(since="5.0.0")
@Override
public Node list(Object... objs) {
return getWhereHandler().list(objs);
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/Converters.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/Converters.java
index 3c80e248e0..066a87a98e 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/Converters.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/Converters.java
@@ -17,11 +17,18 @@
*/
package org.apache.jena.arq.querybuilder;
+import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import org.apache.jena.arq.querybuilder.rewriters.AbstractRewriter;
+import org.apache.jena.arq.querybuilder.rewriters.PathRewriter;
import org.apache.jena.datatypes.BaseDatatype;
import org.apache.jena.datatypes.DatatypeFormatException;
import org.apache.jena.datatypes.RDFDatatype;
@@ -29,16 +36,22 @@ import org.apache.jena.datatypes.TypeMapper;
import org.apache.jena.graph.FrontsNode;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Triple;
import org.apache.jena.riot.RiotException;
import org.apache.jena.riot.system.PrefixMapFactory;
import org.apache.jena.shared.PrefixMapping;
import org.apache.jena.sparql.ARQInternalErrorException;
+import org.apache.jena.sparql.core.TriplePath;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.expr.ExprVar;
+import org.apache.jena.sparql.lang.arq.ARQParser;
+import org.apache.jena.sparql.lang.arq.ParseException;
import org.apache.jena.sparql.path.P_Link;
import org.apache.jena.sparql.path.Path;
import org.apache.jena.sparql.path.PathParser;
+import org.apache.jena.sparql.syntax.TripleCollectorMark;
import org.apache.jena.sparql.util.NodeFactoryExtra;
+import org.apache.jena.vocabulary.RDF;
/**
* A collection of static methods to convert from Objects to various types used
@@ -50,6 +63,16 @@ public class Converters {
// do not make instance
}
+ /**
+ * @param o the object to test.
+ * @return true if the object is a Java collection or a string starting with '(' and ending with ')'
+ */
+ private static boolean isCollection(Object o) {
+ Predicate<String> isLiteralCollection = (s) -> s.charAt(0) == '(' && s.charAt(s.length()-1) == ')';
+ return o != null && (o instanceof Collection ||
+ (o instanceof String && isLiteralCollection.test(((String) o).trim())));
+ }
+
/**
* Converts any Node_Variable nodes into Var nodes.
*
@@ -160,13 +183,13 @@ public class Converters {
if (o instanceof Node) {
return checkVar((Node) o);
}
+
if (o instanceof String) {
try {
return checkVar(NodeFactoryExtra.parseNode((String) o, PrefixMapFactory.create(pMapping)));
} catch (final RiotException e) {
// expected in some cases -- do nothing
}
-
}
return makeLiteral(o);
}
@@ -317,4 +340,365 @@ public class Converters {
return values;
}
+ /**
+ * Gathers the triples and adds them to the collector.
+ * @param collector the collector for the triples.
+ * @param s Subject object may be expanded to an RDF collection.
+ * @param p Subject object may be expanded to an RDF collection.
+ * @param o Subject object may be expanded to an RDF collection.
+ * @param prefixMapping the prefix mapping to use for URI resolution.
+ */
+ private static void gatherTriples(ReadableTripleCollectorMark collector, Object s, Object p, Object o,
+ PrefixMapping prefixMapping) {
+ Node sNode = null;
+ Object pNode = null;
+ Node oNode = null;
+
+ Function<Object, Node> processNode = (n) -> {
+ if (isCollection(n)) {
+ int mark = collector.mark();
+ gatherTriples(collector, n, prefixMapping);
+ return collector.getSubject(mark);
+ }
+ return makeNode(n, prefixMapping);
+ };
+
+ sNode = processNode.apply(s);
+
+ if (isCollection(p)) {
+ int mark = collector.mark();
+ gatherTriples(collector, p, prefixMapping);
+ pNode = collector.getSubject(mark);
+ } else {
+ pNode = makeNodeOrPath(p, prefixMapping);
+ }
+
+ oNode = processNode.apply(o);
+
+ if (pNode instanceof Path) {
+ collector.addTriplePath(new TriplePath(sNode, (Path) pNode, oNode));
+ } else {
+ collector.addTriple(Triple.create(sNode, (Node) pNode, oNode));
+ }
+
+ }
+
+ /**
+ * Creates a collection of {@code TriplePath}s from the {@code s, p, o}. If
+ * {@code s}, {@code p}, or {@code o} is a collection or a String representation of a
+ * collection like {@code "(a, b, c)"} the
+ * {@code makeCollectionTriplePaths()} conversions are applied. If {@code s} and/or
+ * {@code o} is not a collection the {@code makeNode()} conversions are applied.
+ * if {@code p} is not a collection the @{code makeNodeOrPath()} conversion is
+ * applied.
+ * <p><em>Note: Path objects are not supported in RDF collections. A custom Datatype would need
+ * to be registered to place them in collections</em></p>
+ *
+ * @param s the object for the subject.
+ * @param p the object for the predicate.
+ * @param o the object for the object.
+ * @param prefixMapping the PrefixMapping to resolve nodes.
+ * @return A list of {@code TriplePath} objects.
+ * @see #makeNodeOrPath(Object, PrefixMapping)
+ * @see #makeCollectionTriplePaths(Object, PrefixMapping)
+ * @see #makeNode(Object, PrefixMapping)
+ */
+ public static List<TriplePath> makeTriplePaths(Object s, Object p, Object o, PrefixMapping prefixMapping) {
+ ConvertersTriplePathCollector result = new ConvertersTriplePathCollector();
+ gatherTriples(result, s, p, o, prefixMapping);
+ return result.result;
+ }
+
+ /**
+ * Creates a collection of {@code Triple}s from the {@code s, p, o}. If
+ * {@code s}, {@code p}, or {@code o} is a collection or a String representation of a
+ * collection like {@code "(a, b, c)"} the
+ * {@code makeCollectionTriples()} conversions are applied. If {@code s}, {@code p}, or
+ * {@code o} is not a collection the {@code makeNode()} conversions are applied.
+ * This differs from
+ * {@link #makeTriplePaths(Object, Object, Object, PrefixMapping)} in that the
+ * {@code p} may not be a path.
+ *
+ * <p><em>Note: Path objects are not supported in RDF collections. A custom Datatype would need
+ * to be registered to place them in collections</em></p>
+ *
+ * @param s the object for the subject.
+ * @param p the object for the predicate.
+ * @param o the object for the object.
+ * @param prefixMapping the PrefixMapping to resolve nodes.
+ * @return A list of {@code Triple} objects.
+ * @see #makeNodeOrPath(Object, PrefixMapping)
+ * @see #makeCollectionTriples(Object, PrefixMapping)
+ * @see #makeNode(Object, PrefixMapping)
+ */
+ public static List<Triple> makeTriples(Object s, Object p, Object o, PrefixMapping prefixMapping) {
+ ConvertersTripleCollector result = new ConvertersTripleCollector();
+ gatherTriples(result, s, p, o, prefixMapping);
+ return result.result;
+ }
+
+ /**
+ * Creates an RDF collection from a collection object. The collection object may be either
+ * a Java collection or an ARQParser collection literal like {@code "(a, b, c)"}.
+ * @param collector the TripleCollector to add the triples to.
+ * @param collection the collection of objects or string representation of collection to convert.
+ * @param prefixMapping the prefix mapping to use.
+ */
+ @SuppressWarnings("unchecked")
+ private static void gatherTriples(ReadableTripleCollectorMark collector, Object collection,
+ PrefixMapping prefixMapping) {
+ if (collection instanceof Collection) {
+ Node previous = null;
+ for (Object obj : (Collection<Object>) collection) {
+ Node current = NodeFactory.createBlankNode();
+ if (previous != null) {
+ collector.addTriple(Triple.create(previous, RDF.rest.asNode(), current));
+ }
+ if (isCollection(obj)) {
+ int mark = collector.mark();
+ gatherTriples(collector, obj, prefixMapping);
+ collector.addTriple(Triple.create(current, RDF.first.asNode(), collector.getSubject(mark)));
+ } else {
+ collector.addTriple(Triple.create(current, RDF.first.asNode(), makeNode(obj, prefixMapping)));
+ }
+ previous = current;
+ }
+ collector.addTriple(Triple.create(previous, RDF.rest.asNode(), RDF.nil.asNode()));
+ } else {
+ String parserInput = collection.toString().trim();
+ ARQParser parser = new ARQParser(new StringReader(parserInput));
+ int mark = collector.mark();
+ try {
+ parser.CollectionPath(collector);
+ } catch (ParseException e) {
+ throw new IllegalArgumentException(String.format("Unable to parse: %s", collection), e);
+ }
+ collector.rewriteFrom(mark);
+ }
+ }
+
+ /**
+ * Create an RDF collection from a collection of objects as per
+ * <a href='http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#collections'>
+ * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#collections</a>
+ * <p>
+ * Embedded collections are recursively expanded and added to the resulting
+ * list. Other object types in the collections are converted using
+ * {@code makeNode} PrefixMapping)}.
+ * <p>
+ * <p><em>Note: Path objects are not supported in RDF collections. A custom Datatype would need
+ * to be registered to place them in collections</em></p>
+ * Usage:
+ * <ul>
+ * <li>In most cases direct calls to makeCollection are unnecessary as passing
+ * the collection to methods like {@code addWhere(Object, Object, Object)} will
+ * correctly create and add the list.</li>
+ * <li>In cases where makeCollectionTriples is called the Subject of the first
+ * {@code Triple} is the RDF Collection node.</li>
+ * </ul>
+ * </p>
+ *
+ * @param collection the collections of objects for the list.
+ * @return A list of {@code Triple} objects.
+ * @see #makeNode(Object, PrefixMapping)
+ */
+ public static List<Triple> makeCollectionTriples(Object collection, PrefixMapping prefixMapping) {
+ ConvertersTripleCollector collector = new ConvertersTripleCollector();
+ gatherTriples(collector, collection, prefixMapping);
+ return collector.result;
+ }
+
+ /**
+ * Create an RDF collection from a collection of objects as per
+ * <a href='http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#collections'>
+ * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#collections</a>.
+ * <p>
+ * Embedded collections are recursively expanded and added to the resulting
+ * list. Other object types in the collections are converted using
+ * {@code makeNode} PrefixMapping)}.
+ * <p>
+ * <p><em>Note: Path objects are not supported in RDF collections. A custom Datatype would need
+ * to be registered to place them in collections</em></p>
+ * Usage:
+ * <ul>
+ * <li>In most cases direct calls to makeCollectionTriplePaths are unnecessary
+ * as passing the collection to methods like
+ * {@code addWhere(Object, Object, Object)} will correctly create and add the
+ * list.</li>
+ * <li>In cases where makeCollectionTriplePath is called the Subject of the
+ * first {@code TriplePath} is the RDF Collection node.</li>
+ * </ul>
+ * </p>
+ *
+ * @param n the collections of objects for the list.
+ * @return A list of {@code TriplePath} objects.
+ * @see #makeNode(Object, PrefixMapping)
+ */
+ public static List<TriplePath> makeCollectionTriplePaths(Object n, PrefixMapping prefixMapping) {
+ ConvertersTriplePathCollector collector = new ConvertersTriplePathCollector();
+ gatherTriples(collector, n, prefixMapping);
+ return collector.result;
+ }
+
+ /**
+ * defines methods needed by converters to convert collections into into RDF collections.
+ */
+ interface ReadableTripleCollectorMark extends TripleCollectorMark {
+ /**
+ * Get the subject from the entry in the collection at the {@code mark} location.
+ * @param mark the location to retrieve from.
+ * @return the Subject node
+ */
+ Node getSubject(int mark);
+
+ /**
+ * Rewrite the variable nodes in the triples from {@code mark} to the end.
+ * This is required because the parser that converts from literal {@code "(a, b, c)"}
+ * to the RDF list will number the variables from 0.
+ * @param mark the position to start the rewrite from.
+ */
+ void rewriteFrom(int mark);
+ }
+
+ /**
+ * Collects triples only.
+ */
+ private static class ConvertersTripleCollector implements ReadableTripleCollectorMark {
+ List<Triple> result = new ArrayList<>();
+
+ @Override
+ public void addTriple(Triple t) {
+ result.add(t);
+ }
+
+ @Override
+ public void addTriplePath(TriplePath tPath) {
+ throw new IllegalArgumentException("Path is not allowed in a Triple");
+ }
+
+ @Override
+ public int mark() {
+ return result.size();
+ }
+
+ @Override
+ public void addTriple(int index, Triple t) {
+ result.add(index, t);
+ }
+
+ @Override
+ public void addTriplePath(int index, TriplePath tPath) {
+ throw new IllegalArgumentException("Path is not allowed in a Triple");
+ }
+
+ @Override
+ public Node getSubject(int mark) {
+ return result.get(mark).getSubject();
+ }
+
+ @Override
+ public void rewriteFrom(int mark) {
+ Map<Var, Node> values = new HashMap<>();
+ TripleRewriter rewriter = new TripleRewriter(values);
+ for (int i = mark; i < mark(); i++) {
+ result.set(i, rewriter.rewrite(result.get(i)));
+ }
+ }
+ }
+
+ /**
+ * Collects triple paths.
+ */
+ private static class ConvertersTriplePathCollector implements ReadableTripleCollectorMark {
+ List<TriplePath> result = new ArrayList<>();
+
+ @Override
+ public void addTriple(Triple t) {
+ result.add(new TriplePath(t));
+ }
+
+ @Override
+ public void addTriplePath(TriplePath tPath) {
+ result.add(tPath);
+ }
+
+ @Override
+ public int mark() {
+ return result.size();
+ }
+
+ @Override
+ public void addTriple(int index, Triple t) {
+ result.add(index, new TriplePath(t));
+ }
+
+ @Override
+ public void addTriplePath(int index, TriplePath tPath) {
+ result.add(index, tPath);
+ };
+
+ @Override
+ public Node getSubject(int mark) {
+ return result.get(mark).getSubject();
+ }
+
+ @Override
+ public void rewriteFrom(int mark) {
+ Map<Var, Node> values = new HashMap<>();
+ TripleRewriter rewriter = new TripleRewriter(values);
+ for (int i = mark; i < mark(); i++) {
+ result.set(i, rewriter.rewrite(result.get(i)));
+ }
+ }
+ }
+
+ /**
+ * Rewriter implementation to convert the numbered variables to blank nodes.
+ */
+ private static class TripleRewriter extends AbstractRewriter<Node> {
+ private PathRewriter pathRewriter;
+
+ protected TripleRewriter(Map<Var, Node> values) {
+ super(values);
+ pathRewriter = new PathRewriter(values) {
+ @Override
+ protected Node changeNode(Node n) {
+ return TripleRewriter.this.changeNode(n);
+ }
+ };
+ }
+
+ @Override
+ protected Node changeNode(Node n) {
+ if (n == null) {
+ return n;
+ }
+ if (n.isVariable() && n.toString().startsWith("??")) {
+ Var key = Var.alloc(n);
+ Node result = values.get(key);
+ if (result == null) {
+ result = NodeFactory.createBlankNode();
+ values.put(key, result);
+ }
+ return result;
+ }
+ return n;
+ }
+
+ /**
+ * Rewrite a triple path.
+ *
+ * @param t The triple path to rewrite.
+ * @return the triple path after rewriting.
+ */
+ @Override
+ public TriplePath rewrite(TriplePath t) {
+ if (t.getPath() == null) {
+ return new TriplePath(Triple.create(changeNode(t.getSubject()), changeNode(t.getPredicate()),
+ changeNode(t.getObject())));
+ }
+ t.getPath().visit(pathRewriter);
+ return new TriplePath(changeNode(t.getSubject()), pathRewriter.getResult(), changeNode(t.getObject()));
+ }
+ }
}
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/DescribeBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/DescribeBuilder.java
index a80b45a82d..5fdd9f494b 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/DescribeBuilder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/DescribeBuilder.java
@@ -17,6 +17,7 @@
*/
package org.apache.jena.arq.querybuilder;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -197,6 +198,13 @@ public class DescribeBuilder extends AbstractQueryBuilder<DescribeBuilder> imple
getWhereHandler().addWhere(t);
return this;
}
+
+
+ @Override
+ public DescribeBuilder addWhere(Collection<TriplePath> collection) {
+ getWhereHandler().addWhere(collection);
+ return this;
+ }
@Override
public DescribeBuilder addWhere(FrontsTriple t) {
@@ -206,7 +214,7 @@ public class DescribeBuilder extends AbstractQueryBuilder<DescribeBuilder> imple
@Override
public DescribeBuilder addWhere(Object s, Object p, Object o) {
- getWhereHandler().addWhere(makeTriplePath(s, p, o));
+ getWhereHandler().addWhere(makeTriplePaths(s, p, o));
return this;
}
@@ -258,25 +266,29 @@ public class DescribeBuilder extends AbstractQueryBuilder<DescribeBuilder> imple
@Override
public DescribeBuilder addOptional(Triple t) {
- getWhereHandler().addOptional(new TriplePath(t));
- return this;
+ return addOptional(new TriplePath(t));
}
@Override
public DescribeBuilder addOptional(TriplePath t) {
- getWhereHandler().addOptional(t);
+ getWhereHandler().addOptional(Arrays.asList(t));
return this;
}
@Override
public DescribeBuilder addOptional(FrontsTriple t) {
- getWhereHandler().addOptional(new TriplePath(t.asTriple()));
+ return addOptional(new TriplePath(t.asTriple()));
+ }
+
+ @Override
+ public DescribeBuilder addOptional(Collection<TriplePath> collection) {
+ getWhereHandler().addOptional(collection);
return this;
}
@Override
public DescribeBuilder addOptional(Object s, Object p, Object o) {
- getWhereHandler().addOptional(makeTriplePath(s, p, o));
+ getWhereHandler().addOptional(makeTriplePaths(s, p, o));
return this;
}
@@ -319,25 +331,30 @@ public class DescribeBuilder extends AbstractQueryBuilder<DescribeBuilder> imple
@Override
public DescribeBuilder addGraph(Object graph, FrontsTriple triple) {
- getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple.asTriple()));
+ addGraph(graph, new TriplePath(triple.asTriple()));
return this;
}
@Override
public DescribeBuilder addGraph(Object graph, Object subject, Object predicate, Object object) {
- getWhereHandler().addGraph(makeNode(graph), makeTriplePath(subject, predicate, object));
+ getWhereHandler().addGraph(makeNode(graph), makeTriplePaths(subject, predicate, object));
return this;
}
@Override
public DescribeBuilder addGraph(Object graph, Triple triple) {
- getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple));
- return this;
+ return addGraph(graph, new TriplePath(triple));
}
@Override
public DescribeBuilder addGraph(Object graph, TriplePath triplePath) {
- getWhereHandler().addGraph(makeNode(graph), triplePath);
+ getWhereHandler().addGraph(makeNode(graph), Arrays.asList(triplePath));
+ return this;
+ }
+
+ @Override
+ public DescribeBuilder addGraph(Object graph, Collection<TriplePath> collection) {
+ getWhereHandler().addGraph(makeNode(graph), collection);
return this;
}
@@ -353,6 +370,10 @@ public class DescribeBuilder extends AbstractQueryBuilder<DescribeBuilder> imple
return this;
}
+ /*
+ * @deprecated use {@code addWhere(Converters.makeCollection(List.of(Object...)))}, or simply call {@link #addWhere(Object, Object, Object)} passing the collection for one of the objects.
+ */
+ @Deprecated(since="5.0.0")
@Override
public Node list(Object... objs) {
return getWhereHandler().list(objs);
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/SelectBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/SelectBuilder.java
index efc3af28be..2c0a11671c 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/SelectBuilder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/SelectBuilder.java
@@ -17,6 +17,7 @@
*/
package org.apache.jena.arq.querybuilder;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -302,6 +303,14 @@ public class SelectBuilder extends AbstractQueryBuilder<SelectBuilder> implement
return this;
}
+ @Override
+ public SelectBuilder addWhere(Collection<TriplePath> collection) {
+ getWhereHandler().addWhere(collection);
+ return this;
+ }
+
+
+
@Override
public SelectBuilder addWhere(Triple t) {
getWhereHandler().addWhere(new TriplePath(t));
@@ -316,7 +325,7 @@ public class SelectBuilder extends AbstractQueryBuilder<SelectBuilder> implement
@Override
public SelectBuilder addWhere(Object s, Object p, Object o) {
- getWhereHandler().addWhere(makeTriplePath(s, p, o));
+ getWhereHandler().addWhere(makeTriplePaths(s, p, o));
return this;
}
@@ -368,25 +377,29 @@ public class SelectBuilder extends AbstractQueryBuilder<SelectBuilder> implement
@Override
public SelectBuilder addOptional(TriplePath t) {
- getWhereHandler().addOptional(t);
+ getWhereHandler().addOptional(Arrays.asList(t));
return this;
}
@Override
public SelectBuilder addOptional(Triple t) {
- getWhereHandler().addOptional(new TriplePath(t));
- return this;
+ return addOptional(new TriplePath(t));
}
@Override
public SelectBuilder addOptional(FrontsTriple t) {
- getWhereHandler().addOptional(new TriplePath(t.asTriple()));
+ return addOptional(new TriplePath(t.asTriple()));
+ }
+
+ @Override
+ public SelectBuilder addOptional(Collection<TriplePath> collection) {
+ getWhereHandler().addOptional(collection);
return this;
}
@Override
public SelectBuilder addOptional(Object s, Object p, Object o) {
- getWhereHandler().addOptional(makeTriplePath(s, p, o));
+ getWhereHandler().addOptional(makeTriplePaths(s, p, o));
return this;
}
@@ -429,28 +442,32 @@ public class SelectBuilder extends AbstractQueryBuilder<SelectBuilder> implement
@Override
public SelectBuilder addGraph(Object graph, FrontsTriple triple) {
- getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple.asTriple()));
- return this;
+ return addGraph(graph, new TriplePath(triple.asTriple()));
}
@Override
public SelectBuilder addGraph(Object graph, Object subject, Object predicate, Object object) {
- getWhereHandler().addGraph(makeNode(graph), makeTriplePath(subject, predicate, object));
+ getWhereHandler().addGraph(makeNode(graph), makeTriplePaths(subject, predicate, object));
return this;
}
@Override
public SelectBuilder addGraph(Object graph, Triple triple) {
- getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple));
- return this;
+ return addGraph(graph, new TriplePath(triple));
}
@Override
public SelectBuilder addGraph(Object graph, TriplePath triplePath) {
- getWhereHandler().addGraph(makeNode(graph), triplePath);
+ getWhereHandler().addGraph(makeNode(graph), Arrays.asList(triplePath));
return this;
}
+ @Override
+ public SelectBuilder addGraph(Object graph, Collection<TriplePath> collection) {
+ getWhereHandler().addGraph(makeNode(graph), collection);
+ return this;
+ }
+
@Override
public SelectBuilder addBind(Expr expression, Object var) {
getWhereHandler().addBind(expression, Converters.makeVar(var));
@@ -468,7 +485,10 @@ public class SelectBuilder extends AbstractQueryBuilder<SelectBuilder> implement
return handlerBlock.getSelectHandler();
}
- @Override
+ /*
+ * @deprecated use {@code addWhere(Converters.makeCollection(List.of(Object...)))}, or simply call {@link #addWhere(Object, Object, Object)} passing the collection for one of the objects.
+ */
+ @Deprecated(since="5.0.0") @Override
public Node list(Object... objs) {
return getWhereHandler().list(objs);
}
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/UpdateBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/UpdateBuilder.java
index b77418d141..4e021e8c3c 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/UpdateBuilder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/UpdateBuilder.java
@@ -254,7 +254,9 @@ public class UpdateBuilder {
* @param p the predicate object
* @param o the object object.
* @return a TriplePath
+ * @deprecatd use {@link #makeTriplePaths(Object, Object, Object)}
*/
+ @Deprecated(since="5.0.0")
public TriplePath makeTriplePath(Object s, Object p, Object o) {
final Object po = Converters.makeNodeOrPath(p, prefixHandler.getPrefixes());
if (po instanceof Path) {
@@ -262,6 +264,21 @@ public class UpdateBuilder {
}
return new TriplePath(Triple.create(makeNode(s), (Node) po, makeNode(o)));
}
+
+ /**
+ * Make a collection of one or more {@code TriplePath} objects from the objects.
+ *
+ * Uses {@code Converters.makeTriplePaths} to perform the conversions using the prefixes
+ * defined in this UpdateBuilder.
+ *
+ * @param s The subject object
+ * @param p the predicate object
+ * @param o the object object.
+ * @return a collection of {@code TriplePath}s
+ */
+ public Collection<TriplePath> makeTriplePaths(Object s, Object p, Object o) {
+ return Converters.makeTriplePaths(s, p, o, prefixHandler.getPrefixes());
+ }
/**
* Convert the object to a node.
@@ -310,6 +327,18 @@ public class UpdateBuilder {
return Converters.quoted(s);
}
+ /**
+ * Converts the {@code s,p,o} triple into a list of Triples. List will contain multiple
+ * triples if {@code s} or {@code o} are collections.
+ * @param s The subject object
+ * @param p the predicate object.
+ * @param o the object object.
+ * @return A list of triples.
+ */
+ private List<Triple> makeTriples(Object s, Object p, Object o) {
+ return Converters.makeTriples(s, p, o, prefixHandler.getPrefixes());
+ }
+
/**
* Add a quad to the insert statement.
*
@@ -323,7 +352,8 @@ public class UpdateBuilder {
* @return this builder for chaining.
*/
public UpdateBuilder addInsert(Object g, Object s, Object p, Object o) {
- return addInsert(new Quad(makeNode(g), makeNode(s), makeNode(p), makeNode(o)));
+ List<Triple> lst = makeTriples(s, p, o);
+ return lst.size()>1? addInsert(g, lst) : addInsert(g, lst.get(0));
}
/**
@@ -350,8 +380,8 @@ public class UpdateBuilder {
* @return this builder for chaining.
*/
public UpdateBuilder addInsert(Object s, Object p, Object o) {
- addInsert(Triple.create(makeNode(s), makeNode(p), makeNode(o)));
- return this;
+ List<Triple> lst = makeTriples(s, p, o);
+ return lst.size()>1? addInsert(lst) : addInsert(lst.get(0));
}
/**
@@ -513,7 +543,8 @@ public class UpdateBuilder {
* @return this builder for chaining.
*/
public UpdateBuilder addDelete(Object g, Object s, Object p, Object o) {
- return addDelete(new Quad(makeNode(g), makeNode(s), makeNode(p), makeNode(o)));
+ List<Triple> lst = makeTriples(s, p, o);
+ return lst.size()>1? addDelete(g, lst) : addDelete(g, lst.get(0));
}
/**
@@ -550,8 +581,8 @@ public class UpdateBuilder {
* @return this builder for chaining.
*/
public UpdateBuilder addDelete(Object s, Object p, Object o) {
- addDelete(Triple.create(makeNode(s), makeNode(p), makeNode(o)));
- return this;
+ List<Triple> lst = makeTriples(s, p, o);
+ return lst.size()>1? addDelete(lst) : addDelete(lst.get(0));
}
/**
@@ -849,6 +880,19 @@ public class UpdateBuilder {
return this;
}
+ /**
+ * Add an optional triple to the where clause
+ *
+ * @param collection The collection of {@code TriplePath} path to add.
+ * @return The Builder for chaining.
+ * @throws IllegalArgumentException If the triple is not a valid triple for a
+ * where clause.
+ */
+ public UpdateBuilder addOptional(Collection<TriplePath> collection) throws IllegalArgumentException {
+ whereProcessor.addOptional(collection);
+ return this;
+ }
+
/**
* Add the contents of a where handler as an optional statement.
*
@@ -941,7 +985,10 @@ public class UpdateBuilder {
*
* @param objs the list of objects for the list.
* @return the first blank node in the list.
+ * @deprecated use makeList
+ * @see #makeList(Object...)
*/
+ @Deprecated(since="5.0.0")
public Node list(Object... objs) {
Node retval = NodeFactory.createBlankNode();
Node lastObject = retval;
@@ -960,6 +1007,42 @@ public class UpdateBuilder {
return retval;
}
+
+ /**
+ * Create a list node from a list of objects as per RDF Collections.
+ *
+ * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#collections
+ *
+ * See {@link AbstractQueryBuilder#makeNode} for conversion of the param values.
+ * <p>
+ * usage:
+ * <ul>
+ * <li>list( param1, param2, param3, ... )</li>
+ * <li>addWhere( list( param1, param2, param3, ... ), p, o )</li>
+ * <li>addOptional( list( param1, param2, param3, ... ), p, o )</li>
+ * </ul>
+ *
+ * @param objs the list of objects for the list.
+ * @return the first blank node in the list.
+ */
+ public Node makeList(Object... objs) {
+ Node retval = NodeFactory.createBlankNode();
+ Node lastObject = retval;
+ for (int i = 0; i < objs.length; i++) {
+ Node n = makeNode(objs[i]);
+ addWhere(new TriplePath(Triple.create(lastObject, RDF.first.asNode(), n)));
+ if (i + 1 < objs.length) {
+ Node nextObject = NodeFactory.createBlankNode();
+ addWhere(new TriplePath(Triple.create(lastObject, RDF.rest.asNode(), nextObject)));
+ lastObject = nextObject;
+ } else {
+ addWhere(new TriplePath(Triple.create(lastObject, RDF.rest.asNode(), RDF.nil.asNode())));
+ }
+
+ }
+
+ return retval;
+ }
/**
* Adds a triple to the where clause.
@@ -993,7 +1076,8 @@ public class UpdateBuilder {
* @return The Builder for chaining.
*/
public UpdateBuilder addWhere(Object s, Object p, Object o) {
- return addWhere(makeTriplePath(s, p, o));
+ makeTriplePaths(s, p, o).forEach(whereProcessor::addWhere);
+ return this;
}
/**
@@ -1028,7 +1112,8 @@ public class UpdateBuilder {
* @return The Builder for chaining.
*/
public UpdateBuilder addOptional(Object s, Object p, Object o) {
- return addOptional(makeTriplePath(s, p, o));
+ makeTriplePaths(s, p, o).forEach(whereProcessor::addOptional);
+ return this;
}
/**
@@ -1154,4 +1239,5 @@ public class UpdateBuilder {
QuadAcc quadAcc = new QuadAcc(new QBQuadHolder(queryBuilder).getQuads().toList());
return new UpdateDeleteWhere(quadAcc);
}
+
}
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/WhereBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/WhereBuilder.java
index d152a7ddb2..3b05fa7aaa 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/WhereBuilder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/WhereBuilder.java
@@ -18,6 +18,7 @@
package org.apache.jena.arq.querybuilder;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -63,6 +64,12 @@ public class WhereBuilder extends AbstractQueryBuilder<WhereBuilder> implements
return this;
}
+ @Override
+ public WhereBuilder addWhere(Collection<TriplePath> collection) {
+ getWhereHandler().addWhere(collection);
+ return this;
+ }
+
@Override
public WhereBuilder addWhere(FrontsTriple t) {
return addWhere(t.asTriple());
@@ -70,7 +77,8 @@ public class WhereBuilder extends AbstractQueryBuilder<WhereBuilder> implements
@Override
public WhereBuilder addWhere(Object s, Object p, Object o) {
- return addWhere(makeTriplePath(s, p, o));
+ handler.addWhere(makeTriplePaths(s, p, o));
+ return this;
}
@Override
@@ -125,21 +133,27 @@ public class WhereBuilder extends AbstractQueryBuilder<WhereBuilder> implements
return this;
}
+ @Override
+ public WhereBuilder addOptional(Collection<TriplePath> collection) {
+ getWhereHandler().addOptional(collection);
+ return this;
+ }
+
@Override
public WhereBuilder addOptional(Triple t) {
- getWhereHandler().addOptional(new TriplePath(t));
+ addOptional(new TriplePath(t));
return this;
}
@Override
public WhereBuilder addOptional(FrontsTriple t) {
- getWhereHandler().addOptional(new TriplePath(t.asTriple()));
+ addOptional(new TriplePath(t.asTriple()));
return this;
}
@Override
public WhereBuilder addOptional(Object s, Object p, Object o) {
- getWhereHandler().addOptional(makeTriplePath(s, p, o));
+ getWhereHandler().addOptional(makeTriplePaths(s, p, o));
return this;
}
@@ -182,28 +196,34 @@ public class WhereBuilder extends AbstractQueryBuilder<WhereBuilder> implements
@Override
public WhereBuilder addGraph(Object graph, FrontsTriple triple) {
- getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple.asTriple()));
+ addGraph(graph, new TriplePath(triple.asTriple()));
return this;
}
@Override
public WhereBuilder addGraph(Object graph, Object subject, Object predicate, Object object) {
- getWhereHandler().addGraph(makeNode(graph), makeTriplePath(subject, predicate, object));
+ getWhereHandler().addGraph(makeNode(graph), makeTriplePaths(subject, predicate, object));
return this;
}
@Override
public WhereBuilder addGraph(Object graph, Triple triple) {
- getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple));
+ addGraph(makeNode(graph), new TriplePath(triple));
return this;
}
@Override
public WhereBuilder addGraph(Object graph, TriplePath triplePath) {
- getWhereHandler().addGraph(makeNode(graph), triplePath);
+ getWhereHandler().addGraph(makeNode(graph), Arrays.asList(triplePath));
return this;
}
+ @Override
+ public WhereBuilder addGraph(Object graph, Collection<TriplePath> collection) {
+ getWhereHandler().addGraph(makeNode(graph), collection);
+ return this;
+ }
+
@Override
public WhereBuilder addBind(Expr expression, Object var) {
getWhereHandler().addBind(expression, Converters.makeVar(var));
@@ -216,7 +236,10 @@ public class WhereBuilder extends AbstractQueryBuilder<WhereBuilder> implements
return this;
}
- @Override
+ /*
+ * @deprecated use {@code addWhere(Converters.makeCollection(List.of(Object...)))}, or simply call {@link #addWhere(Object, Object, Object)} passing the collection for one of the objects.
+ */
+ @Deprecated(since="5.0.0") @Override
public Node list(Object... objs) {
return getWhereHandler().list(objs);
}
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/WhereClause.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/WhereClause.java
index 5cae86d6ae..1c5dcf914e 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/WhereClause.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/WhereClause.java
@@ -43,7 +43,7 @@ public interface WhereClause<T extends AbstractQueryBuilder<T>> {
/**
* Adds a triple to the where clause.
*
- * @param t The triple path to add
+ * @param t The triple to add
* @return This Builder for chaining.
*/
public T addWhere(Triple t);
@@ -55,6 +55,15 @@ public interface WhereClause<T extends AbstractQueryBuilder<T>> {
* @return This Builder for chaining.
*/
public T addWhere(TriplePath t);
+
+ /**
+ * Adds a collections of triple paths to the where clause.
+ *
+ * @param collection The collection of triple paths to add
+ * @return This Builder for chaining.
+ */
+ public T addWhere(Collection<TriplePath> collection);
+
/**
* Adds a triple to the where clause.
@@ -227,6 +236,14 @@ public interface WhereClause<T extends AbstractQueryBuilder<T>> {
* @return This Builder for chaining.
*/
public T addOptional(TriplePath t);
+
+ /**
+ * Adds a collection of triple paths as the optional clauses.
+ *
+ * @param collection The collection of triple paths to add
+ * @return This Builder for chaining.
+ */
+ public T addOptional(Collection<TriplePath> collection);
/**
* Adds an optional triple as to the where clause.
@@ -357,6 +374,15 @@ public interface WhereClause<T extends AbstractQueryBuilder<T>> {
* @return This builder for chaining.
*/
public T addGraph(Object graph, TriplePath triplePath);
+
+ /**
+ * Adds a collection of triple paths as the optional clauses.
+ *
+ * @param graph The iri or variable identifying the graph.
+ * @param collection The collection of triple paths to add
+ * @return This Builder for chaining.
+ */
+ public T addGraph(Object graph, Collection<TriplePath> collection);
/**
* Add a bind statement to the query *
@@ -401,7 +427,9 @@ public interface WhereClause<T extends AbstractQueryBuilder<T>> {
*
* @param objs the list of objects for the list.
* @return the first blank node in the list.
+ * @deprecated use {@code addWhere(Converters.makeCollection(List.of(Object...)))}, or simply call {@link #addWhere(Object, Object, Object)} passing the collection for one of the objects.
*/
+ @Deprecated(since="5.0.0")
public Node list(Object... objs);
/**
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/WhereHandler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/WhereHandler.java
index 565cc13f8b..76582a1787 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/WhereHandler.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/WhereHandler.java
@@ -189,11 +189,11 @@ public class WhereHandler implements Handler {
t.getSubject()));
}
if (!validPredicate) {
- sb.append(String.format("Predicate (%s) must be a Path, URI , variable, or a wildcard. %n",
+ sb.append(String.format("Predicate (%s) must be a Path, URI, variable, or a wildcard. %n",
t.getPredicate()));
}
if (!validObject) {
- sb.append(String.format("Object (%s) must be a URI, literal, blank, , variable, or a wildcard. %n",
+ sb.append(String.format("Object (%s) must be a URI, literal, blank, variable, or a wildcard. %n",
t.getObject()));
}
if (!validSubject || !validPredicate) {
@@ -227,13 +227,24 @@ public class WhereHandler implements Handler {
ElementPathBlock epb = (ElementPathBlock) e;
epb.addTriple(t);
} else {
- ElementPathBlock etb = new ElementPathBlock();
- etb.addTriple(t);
- eg.addElement(etb);
+ ElementPathBlock epb = new ElementPathBlock();
+ epb.addTriple(t);
+ eg.addElement(epb);
}
}
}
+
+ /**
+ * Add the triple path to the where clause
+ *
+ * @param t The triple path to add.
+ * @throws IllegalArgumentException If the triple path is not a valid triple
+ * path for a where clause.
+ */
+ public void addWhere(Collection<TriplePath> t) throws IllegalArgumentException {
+ t.forEach(this::addWhere);
+ }
/**
* Add the triple path to the where clause
@@ -254,9 +265,19 @@ public class WhereHandler implements Handler {
* where clause.
*/
public void addOptional(TriplePath t) throws IllegalArgumentException {
- testTriple(t);
+ addOptional(Arrays.asList(t));
+ }
+
+ /**
+ * Add an optional triple to the where clause
+ *
+ * @param t The triple path to add.
+ * @throws IllegalArgumentException If the triple is not a valid triple for a
+ * where clause.
+ */
+ public void addOptional(Collection<TriplePath> t) throws IllegalArgumentException {
ElementPathBlock epb = new ElementPathBlock();
- epb.addTriple(t);
+ t.forEach( tp -> {testTriple(tp);epb.addTriple(tp);});
ElementOptional opt = new ElementOptional(epb);
getClause().addElement(opt);
}
@@ -381,6 +402,20 @@ public class WhereHandler implements Handler {
epb.addTriple(subQuery);
getClause().addElement(new ElementNamedGraph(graph, epb));
}
+
+ /**
+ * Add a graph to the where clause.
+ *
+ * Short hand for graph { s, p, o }
+ *
+ * @param graph The name of the graph.
+ * @param subQuery A triple path to add to the graph.
+ */
+ public void addGraph(Node graph, Collection<TriplePath> subQuery) {
+ ElementPathBlock epb = new ElementPathBlock();
+ subQuery.forEach(epb::addTriple);
+ getClause().addElement(new ElementNamedGraph(graph, epb));
+ }
/**
* Add a binding to the where clause.
@@ -445,7 +480,9 @@ public class WhereHandler implements Handler {
*
* @param objs the list of objects for the list.
* @return the first blank node in the list.
+ * @deprecated use {code Converters.makeCollection(List.of(Object...))}.
*/
+ @Deprecated(since="5.0.0")
public Node list(Object... objs) {
Node retval = NodeFactory.createBlankNode();
Node lastObject = retval;
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/AbstractRewriter.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/AbstractRewriter.java
index 3531a8d1f3..ceb4bff159 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/AbstractRewriter.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/AbstractRewriter.java
@@ -100,7 +100,7 @@ public class AbstractRewriter<T> {
* @param t The triple path to rewrite.
* @return the triple path after rewriting.
*/
- protected final TriplePath rewrite(TriplePath t) {
+ public TriplePath rewrite(TriplePath t) {
if (t.getPath() == null) {
return new TriplePath(
Triple.create(changeNode(t.getSubject()), changeNode(t.getPredicate()), changeNode(t.getObject())));
@@ -116,7 +116,7 @@ public class AbstractRewriter<T> {
* @param t The triple to rewrite.
* @return The rewritten triple.
*/
- protected final Triple rewrite(Triple t) {
+ public final Triple rewrite(Triple t) {
return Triple.create(changeNode(t.getSubject()), changeNode(t.getPredicate()), changeNode(t.getObject()));
}
@@ -127,7 +127,7 @@ public class AbstractRewriter<T> {
* @param n The node to rewrite.
* @return the rewritten node.
*/
- protected final Node changeNode(Node n) {
+ protected Node changeNode(Node n) {
if (n == null) {
return n;
}
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/WhereQuadHolder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/WhereQuadHolder.java
index 83fac9e6cf..9a3299786d 100644
--- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/WhereQuadHolder.java
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/WhereQuadHolder.java
@@ -17,6 +17,7 @@
*/
package org.apache.jena.arq.querybuilder.updatebuilder;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -221,6 +222,17 @@ public class WhereQuadHolder implements QuadHolder {
}
}
+ /**
+ * Add a {@code TriplePath} collection to the where clause
+ *
+ * @param t The triple path to add.
+ * @throws IllegalArgumentException If the triple path is not a valid triple
+ * path for a where clause.
+ */
+ public void addWhere(Collection<TriplePath> t) throws IllegalArgumentException {
+ t.forEach(this::addWhere);
+ }
+
/**
* Add an optional triple to the where clause
*
@@ -235,6 +247,20 @@ public class WhereQuadHolder implements QuadHolder {
ElementOptional opt = new ElementOptional(epb);
getClause().addElement(opt);
}
+
+ /**
+ * Add an optional TriplePath to the where clause
+ *
+ * @param t The triple path to add.
+ * @throws IllegalArgumentException If the triple is not a valid triple for a
+ * where clause.
+ */
+ public void addOptional(Collection<TriplePath> t) throws IllegalArgumentException {
+ ElementPathBlock epb = new ElementPathBlock();
+ t.forEach( tp -> {testTriple(tp);epb.addTriple(tp);});
+ ElementOptional opt = new ElementOptional(epb);
+ getClause().addElement(opt);
+ }
/**
* Add the contents of a where handler as an optional statement.
@@ -379,7 +405,9 @@ public class WhereQuadHolder implements QuadHolder {
*
* @param objs the list of objects for the list.
* @return the first blank node in the list.
+ * @deprecated use {@code Converters.makeCollection(List.of(Object...))}
*/
+ @Deprecated(since="5.0.0")
public Node list(Object... objs) {
Node retval = NodeFactory.createBlankNode();
Node lastObject = retval;
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/TestAbstractQueryBuilder.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/TestAbstractQueryBuilder.java
new file mode 100644
index 0000000000..08439f8cab
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/TestAbstractQueryBuilder.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jena.arq;
+
+import org.apache.jena.arq.querybuilder.AbstractQueryBuilder;
+import org.apache.jena.arq.querybuilder.handlers.HandlerBlock;
+import org.apache.jena.query.QueryFactory;
+
+/**
+ * Class to create AbstractQueryBuilders for AbstractQueryBuilder parameter tests.
+ */
+@SuppressWarnings("rawtypes")
+public class TestAbstractQueryBuilder extends AbstractQueryBuilder {
+
+ public HandlerBlock handlerBlock = new HandlerBlock( QueryFactory.create());
+
+ @Override
+ public HandlerBlock getHandlerBlock() {
+ return handlerBlock;
+ }
+
+}
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java
index faa20e7d1b..32c804434e 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java
@@ -30,8 +30,8 @@ import org.apache.jena.arq.querybuilder.handlers.HandlerBlock;
import org.apache.jena.datatypes.xsd.XSDDatatype;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.NodeFactory;
-import org.apache.jena.graph.impl.LiteralLabel;
-import org.apache.jena.graph.impl.LiteralLabelFactory;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.sparql.core.TriplePath;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.vocabulary.RDF;
import org.junit.Before;
@@ -131,9 +131,47 @@ public class AbstractQueryBuilderTest {
assertTrue(result.contains(NodeFactory.createURI("one")));
Node n = NodeFactory.createLiteral("5", XSDDatatype.XSDint);
- LiteralLabel ll = LiteralLabelFactory.createTypedLiteral(Integer.valueOf(5));
assertTrue(result.contains(n));
}
+
+ private void assertTripleMatch(Triple expected, Triple actual) {
+ if (!expected.matches(actual)) {
+ fail("expected: "+expected+" actual: "+actual);
+ }
+ }
+
+ private void assertTripleMatch(Triple expected, TriplePath actual) {
+ assertTripleMatch(expected, actual.asTriple());
+ }
+
+ @Test
+ public void testMakeTriplePaths() {
+ List<Object> list = new ArrayList<Object>();
+ list.add(RDF.type);
+ builder.addPrefix("demo", "http://example.com/");
+ list.add("demo:type");
+ list.add("<one>");
+ list.add(Integer.valueOf(5));
+
+ Triple[] expected = {
+ Triple.create(Node.ANY, RDF.first.asNode(), RDF.type.asNode()),
+ Triple.create(Node.ANY, RDF.rest.asNode(), Node.ANY),
+ Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createURI("http://example.com/type")),
+ Triple.create(Node.ANY, RDF.rest.asNode(), Node.ANY),
+ Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createURI("one")),
+ Triple.create(Node.ANY, RDF.rest.asNode(), Node.ANY),
+ Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createLiteral("5", XSDDatatype.XSDint)),
+ Triple.create(Node.ANY, RDF.rest.asNode(), RDF.nil.asNode()),
+ Triple.create(Var.alloc("s"), Var.alloc("p"), Node.ANY),
+ };
+
+ List<TriplePath> result = builder.makeTriplePaths("?s", "?p", list);
+
+ assertEquals(expected.length, result.size());
+ for (int i=0;i<expected.length;i++) {
+ assertTripleMatch( expected[i], result.get(i));
+ }
+ }
}
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java
index 76df142fe0..1bcaa7811e 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java
@@ -99,6 +99,7 @@ public class AskBuilderTest extends AbstractRegexpBasedTest {
query);
}
+ @SuppressWarnings("deprecation")
@Test
public void testList() {
builder.addWhere(builder.list("<one>", "?two", "'three'"), "<foo>", "<bar>");
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java
index 9eb7c72434..87bba2a9e4 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java
@@ -102,6 +102,7 @@ public class ConstructBuilderTest extends AbstractRegexpBasedTest {
query);
}
+ @SuppressWarnings("deprecation")
@Test
public void testList() {
builder.addWhere(builder.list("<one>", "?two", "'three'"), "<foo>", "<bar>");
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConvertersTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConvertersTest.java
index c1c64276d9..e3c3b8ebf8 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConvertersTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConvertersTest.java
@@ -18,7 +18,11 @@
package org.apache.jena.arq.querybuilder;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.net.MalformedURLException;
import java.net.URL;
@@ -34,11 +38,15 @@ import org.apache.jena.datatypes.xsd.XSDDatatype;
import org.apache.jena.graph.FrontsNode;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Triple;
import org.apache.jena.reasoner.rulesys.Node_RuleVariable;
import org.apache.jena.shared.PrefixMapping;
+import org.apache.jena.sparql.core.TriplePath;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.expr.ExprVar;
+import org.apache.jena.sparql.path.P_Link;
import org.apache.jena.sparql.path.Path;
+import org.apache.jena.sparql.util.NodeIsomorphismMap;
import org.apache.jena.vocabulary.RDF;
import org.junit.After;
import org.junit.Test;
@@ -293,6 +301,121 @@ public class ConvertersTest {
assertEquals("\"'I am the \"one\"'\"", Converters.quoted("'I am the \"one\"'"));
}
+ private Node getSubject(Object o) {
+ if (o instanceof Triple) {
+ return ((Triple) o).getSubject();
+ }
+ if (o instanceof TriplePath) {
+ return ((TriplePath) o).getSubject();
+ }
+ throw new IllegalArgumentException("o must be Triple or TriplePath");
+ }
+
+ private static List<Object> theTestList = List.of("<one>", "(<two>)", "('an' <embedded> \"array\")", Node.ANY);
+
+ private void assertExpectedTripleList(List<?> lst) {
+
+ assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createURI("one")), lst.get(0));
+ assertTriplePath(Triple.create(getSubject(lst.get(0)), RDF.rest.asNode(), getSubject(lst.get(4))), lst.get(1));
+ // sublist 1
+ assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createURI("two")), lst.get(2));
+ assertTriplePath(Triple.create(getSubject(lst.get(2)), RDF.rest.asNode(), RDF.nil.asNode()), lst.get(3));
+ // end of sublist 1
+ assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), getSubject(lst.get(2))), lst.get(4));
+ assertTriplePath(Triple.create(getSubject(lst.get(4)), RDF.rest.asNode(), getSubject(lst.get(12))), lst.get(5));
+ // sublist 2
+ assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createLiteral("an")), lst.get(6));
+ assertTriplePath(Triple.create(getSubject(lst.get(6)), RDF.rest.asNode(), getSubject(lst.get(8))), lst.get(7));
+ assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createURI("embedded")), lst.get(8));
+ assertTriplePath(Triple.create(getSubject(lst.get(8)), RDF.rest.asNode(), getSubject(lst.get(10))), lst.get(9));
+ assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), NodeFactory.createLiteral("array")), lst.get(10));
+ assertTriplePath(Triple.create(getSubject(lst.get(10)), RDF.rest.asNode(), RDF.nil.asNode()), lst.get(11));
+ // end of sublist 2
+ assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), getSubject(lst.get(6))), lst.get(12));
+ assertTriplePath(Triple.create(getSubject(lst.get(12)), RDF.rest.asNode(), getSubject(lst.get(14))),
+ lst.get(13));
+ assertTriplePath(Triple.create(Node.ANY, RDF.first.asNode(), Node.ANY), lst.get(14));
+ assertTriplePath(Triple.create(getSubject(lst.get(14)), RDF.rest.asNode(), RDF.nil.asNode()), lst.get(15));
+ }
+
+ @Test
+ public void makeCollectionTriplesTest() {
+ PrefixMapping pMap = PrefixMapping.Factory.create();
+ pMap.setNsPrefixes(PrefixMapping.Standard);
+
+ List<Triple> lst = Converters.makeCollectionTriples(theTestList, pMap);
+ assertEquals(16, lst.size());
+ assertExpectedTripleList(lst);
+ }
+
+ private Triple asTriple(Object o) {
+ if (o instanceof Triple) {
+ return (Triple) o;
+ }
+ if (o instanceof TriplePath) {
+ return ((TriplePath) o).asTriple();
+ }
+ throw new IllegalArgumentException("o must be Triple or TriplePath");
+ }
+
+ private TriplePath asTriplePath(Object o) {
+ if (o instanceof Triple) {
+ return new TriplePath((Triple) o);
+ }
+ if (o instanceof TriplePath) {
+ return (TriplePath) o;
+ }
+ throw new IllegalArgumentException("o must be Triple or TriplePath");
+ }
+
+ private void assertTriplePath(TriplePath expected, Object actual) {
+ String errMsg = String.format("Expected '%s', actual '%s'", expected, actual);
+ if (expected.isTriple()) {
+ assertTrue(errMsg, expected.asTriple().matches(asTriple(actual)));
+ } else {
+ assertTrue(errMsg, expected.getSubject().matches(asTriplePath(actual).getSubject()));
+ assertTrue(errMsg, expected.getObject().matches(asTriplePath(actual).getObject()));
+ assertTrue(errMsg, expected.getPath().equalTo(asTriplePath(actual).getPath(), new NodeIsomorphismMap()));
+ }
+ }
+
+ private void assertTriplePath(Triple expected, Object actual) {
+ String errMsg = String.format("Expected '%s', actual '%s'", expected, actual);
+ assertTrue(errMsg, expected.matches(asTriple(actual)));
+ }
+
+ @Test
+ public void makeCollectionTriplePathsTest() {
+ PrefixMapping pMap = PrefixMapping.Factory.create();
+ pMap.setNsPrefixes(PrefixMapping.Standard);
+ List<TriplePath> lst = Converters.makeCollectionTriplePaths(theTestList, pMap);
+ assertEquals(16, lst.size());
+ assertExpectedTripleList(lst);
+ }
+
+ @Test
+ public void makeTriplePathsTest() {
+ PrefixMapping pMap = PrefixMapping.Factory.create();
+ Path p = new P_Link(NodeFactory.createURI("foo"));
+
+ List<TriplePath> result = Converters.makeTriplePaths("<s>", p, theTestList, pMap);
+ assertExpectedTripleList(result);
+ assertEquals(17, result.size());
+ assertTriplePath(new TriplePath(NodeFactory.createURI("s"), p, result.get(0).getSubject()), result.get(16));
+ }
+
+ @Test
+ public void makeTriplesTest() {
+ PrefixMapping pMap = PrefixMapping.Factory.create();
+
+ List<Triple> result = Converters.makeTriples("<s>", "<p>", theTestList, pMap);
+ assertExpectedTripleList(result);
+ assertEquals(17, result.size());
+ assertTriplePath(
+ Triple.create(NodeFactory.createURI("s"), NodeFactory.createURI("p"), result.get(0).getSubject()),
+ result.get(16));
+ }
+
private class NodeFront implements FrontsNode {
Node n;
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java
index 2183f7b646..de96b2ea53 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java
@@ -36,7 +36,6 @@ import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.sparql.core.TriplePath;
import org.apache.jena.sparql.core.Var;
-import org.apache.jena.sparql.lang.sparql_11.ParseException;
import org.apache.jena.sparql.syntax.ElementPathBlock;
import org.apache.jena.vocabulary.RDF;
import org.apache.jena.vocabulary.XSD;
@@ -55,7 +54,7 @@ public class SelectBuilderTest extends AbstractRegexpBasedTest {
@Test
public void testSelectAsterisk() {
builder.addVar("*").addWhere("?s", "?p", "?o");
-
+
assertContainsRegex(SELECT + "\\*" + SPACE + WHERE + OPEN_CURLY + var("s") + SPACE + var("p") + SPACE + var("o")
+ OPT_SPACE + CLOSE_CURLY, builder.buildString());
@@ -126,14 +125,13 @@ public class SelectBuilderTest extends AbstractRegexpBasedTest {
@Test
public void testNoVars() {
builder.addWhere("?s", "?p", "?o");
- String query = builder.buildString();
-
- assertContainsRegex(SELECT + "\\*" + SPACE, query);
+ Query q = builder.build();
+ assertTrue( q.isQueryResultStar() );
}
+ @SuppressWarnings("deprecation")
@Test
public void testList() {
-
builder.addVar("*").addWhere(builder.list("<one>", "?two", "'three'"), "<foo>", "<bar>");
Query query = builder.build();
@@ -175,7 +173,7 @@ public class SelectBuilderTest extends AbstractRegexpBasedTest {
}
@Test
- public void testAggregatorsInSelect() throws ParseException {
+ public void testAggregatorsInSelect() {
builder.addVar("?x").addVar("count(*)", "?c").addWhere("?x", "?p", "?o").addGroupBy("?x");
Model m = ModelFactory.createDefaultModel();
@@ -218,7 +216,7 @@ public class SelectBuilderTest extends AbstractRegexpBasedTest {
}
@Test
- public void testAggregatorsInSubQuery() throws ParseException {
+ public void testAggregatorsInSubQuery() {
Model m = ModelFactory.createDefaultModel();
Resource r = m.createResource("urn:one");
@@ -250,7 +248,7 @@ public class SelectBuilderTest extends AbstractRegexpBasedTest {
}
@Test
- public void testVarReplacementInSubQuery() throws ParseException {
+ public void testVarReplacementInSubQuery() {
Model m = ModelFactory.createDefaultModel();
Resource r = m.createResource("urn:one");
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierTest.java
index 2180e5acb9..e3011486eb 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierTest.java
@@ -37,7 +37,6 @@ import org.apache.jena.sparql.expr.E_Random;
import org.apache.jena.sparql.expr.Expr;
import org.apache.jena.sparql.expr.ExprVar;
import org.apache.jena.sparql.expr.nodevalue.NodeValueInteger;
-import org.apache.jena.sparql.lang.sparql_11.ParseException;
import org.junit.After;
import org.junit.Assert;
import org.xenei.junit.contract.Contract;
@@ -297,7 +296,7 @@ public class SolutionModifierTest<T extends SolutionModifierClause<?>> extends A
}
@ContractTest
- public void testAddHavingString() throws ParseException {
+ public void testAddHavingString() {
SolutionModifierClause<?> solutionModifier = getProducer().newInstance();
AbstractQueryBuilder<?> builder = solutionModifier.addHaving("?foo<10");
@@ -334,7 +333,7 @@ public class SolutionModifierTest<T extends SolutionModifierClause<?>> extends A
}
@ContractTest
- public void testAddHavingObject() throws ParseException {
+ public void testAddHavingObject() {
SolutionModifierClause<?> solutionModifier = getProducer().newInstance();
AbstractQueryBuilder<?> builder = solutionModifier.addHaving(Var.alloc("foo"));
@@ -361,7 +360,7 @@ public class SolutionModifierTest<T extends SolutionModifierClause<?>> extends A
}
@ContractTest
- public void testAddHavingExpr() throws ParseException {
+ public void testAddHavingExpr() {
SolutionModifierClause<?> solutionModifier = getProducer().newInstance();
AbstractQueryBuilder<?> builder = solutionModifier.addHaving(new E_Random());
@@ -468,7 +467,7 @@ public class SolutionModifierTest<T extends SolutionModifierClause<?>> extends A
}
@ContractTest
- public void testSetVarsHaving() throws ParseException {
+ public void testSetVarsHaving() {
Var v = Var.alloc("v");
SolutionModifierClause<?> solutionModifier = getProducer().newInstance();
AbstractQueryBuilder<?> builder = solutionModifier.addHaving("?v");
@@ -484,7 +483,7 @@ public class SolutionModifierTest<T extends SolutionModifierClause<?>> extends A
}
@ContractTest
- public void testSetVarsHaving_Node_Variable() throws ParseException {
+ public void testSetVarsHaving_Node_Variable() {
Node v = NodeFactory.createVariable("v");
SolutionModifierClause<?> solutionModifier = getProducer().newInstance();
AbstractQueryBuilder<?> builder = solutionModifier.addHaving(v);
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
index 14824a6792..c2cd83338f 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue;
import java.util.*;
+import org.apache.jena.arq.TestAbstractQueryBuilder;
import org.apache.jena.arq.querybuilder.AbstractQueryBuilder;
import org.apache.jena.arq.querybuilder.SelectBuilder;
import org.apache.jena.arq.querybuilder.WhereBuilder;
@@ -44,7 +45,6 @@ import org.apache.jena.sparql.expr.E_Random;
import org.apache.jena.sparql.expr.Expr;
import org.apache.jena.sparql.expr.ExprVar;
import org.apache.jena.sparql.expr.nodevalue.NodeValueInteger;
-import org.apache.jena.sparql.lang.sparql_11.ParseException;
import org.apache.jena.sparql.path.P_Link;
import org.apache.jena.sparql.path.P_Seq;
import org.apache.jena.sparql.path.Path;
@@ -59,7 +59,7 @@ import org.xenei.junit.contract.IProducer;
@Contract(WhereClause.class)
public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTest {
- // the producer we will user
+ // the producer we will use
private IProducer<T> producer;
@Contract.Inject
@@ -78,7 +78,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
}
@ContractTest
- public void testAddWhereStrings() {
+ public void testAddWhere3Objects() {
WhereClause<?> whereClause = getProducer().newInstance();
AbstractQueryBuilder<?> builder = whereClause.addWhere("<one>", "<two>", "three");
@@ -91,6 +91,102 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
builder.build().getQueryPattern().visit(visitor);
assertTrue(visitor.matching);
}
+
+
+ @ContractTest
+ public void testAddWhereAbstractQueryBuilder() {
+ WhereClause<?> whereClause = getProducer().newInstance();
+ TriplePath tp = new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three")));
+
+ TestAbstractQueryBuilder abstractQueryBuilder = new TestAbstractQueryBuilder();
+ abstractQueryBuilder.getHandlerBlock().getWhereHandler().addWhere(tp);
+ AbstractQueryBuilder<?> builder = whereClause.addWhere(abstractQueryBuilder);
+
+ ElementPathBlock epb = new ElementPathBlock();
+ epb.addTriplePath(tp);
+ WhereValidator visitor = new WhereValidator(epb);
+ builder.build().getQueryPattern().visit(visitor);
+ assertTrue(visitor.matching);
+ }
+
+ @ContractTest
+ public void testAddWhereTriplePath() {
+ WhereClause<?> whereClause = getProducer().newInstance();
+ PrefixMapping pmap = new PrefixMappingImpl();
+ pmap.setNsPrefix("ts", "urn:test:");
+ Path path = PathParser.parse("ts:two/ts:dos", pmap);
+ TriplePath first = new TriplePath(NodeFactory.createURI("one"), path, NodeFactory.createURI("three"));
+
+ AbstractQueryBuilder<?> builder = whereClause
+ .addWhere(first);
+
+ ElementPathBlock epb = new ElementPathBlock();
+ epb.addTriplePath(first);
+
+ WhereValidator visitor = new WhereValidator(epb);
+ builder.build().getQueryPattern().visit(visitor);
+ assertTrue(visitor.matching);
+ }
+
+
+ @ContractTest
+ public void testAddWhereTriple() {
+ WhereClause<?> whereClause = getProducer().newInstance();
+ Triple triple = Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three"));
+
+ AbstractQueryBuilder<?> builder = whereClause
+ .addWhere(triple);
+
+ ElementPathBlock epb = new ElementPathBlock();
+ epb.addTriple(triple);
+
+ WhereValidator visitor = new WhereValidator(epb);
+ builder.build().getQueryPattern().visit(visitor);
+ assertTrue(visitor.matching);
+ }
+
+ @ContractTest
+ public void testAddWhereFrontsTriple() {
+ WhereClause<?> whereClause = getProducer().newInstance();
+ Triple triple = Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three"));
+ FrontsTriple front = new FrontsTriple() {
+
+ @Override
+ public Triple asTriple() {
+ return triple;
+ }};
+
+ AbstractQueryBuilder<?> builder = whereClause
+ .addWhere(front);
+
+ ElementPathBlock epb = new ElementPathBlock();
+ epb.addTriple(triple);
+
+ WhereValidator visitor = new WhereValidator(epb);
+ builder.build().getQueryPattern().visit(visitor);
+ assertTrue(visitor.matching);
+ }
+
+ @ContractTest
+ public void testAddWhereTriplePathCollection() {
+ WhereClause<?> whereClause = getProducer().newInstance();
+ PrefixMapping pmap = new PrefixMappingImpl();
+ pmap.setNsPrefix("ts", "urn:test:");
+ Path path = PathParser.parse("ts:two/ts:dos", pmap);
+ TriplePath first = new TriplePath(NodeFactory.createURI("one"), path, NodeFactory.createURI("three"));
+ TriplePath second = new TriplePath(NodeFactory.createURI("for"), path, NodeFactory.createURI("six"));
+
+ AbstractQueryBuilder<?> builder = whereClause
+ .addWhere(List.of(first, second));
+
+ ElementPathBlock epb = new ElementPathBlock();
+ epb.addTriplePath(first);
+ epb.addTriplePath(second);
+
+ WhereValidator visitor = new WhereValidator(epb);
+ builder.build().getQueryPattern().visit(visitor);
+ assertTrue(visitor.matching);
+ }
@ContractTest
public void testAddWhereWhereClause() {
@@ -196,6 +292,28 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
assertTrue(visitor.matching);
}
+ @ContractTest
+ public void testAddOptionalTriplePathCollection() {
+ WhereClause<?> whereClause = getProducer().newInstance();
+ PrefixMapping pmap = new PrefixMappingImpl();
+ pmap.setNsPrefix("ts", "urn:test:");
+ Path path = PathParser.parse("ts:two/ts:dos", pmap);
+ TriplePath first = new TriplePath(NodeFactory.createURI("one"), path, NodeFactory.createURI("three"));
+ TriplePath second = new TriplePath(NodeFactory.createURI("for"), path, NodeFactory.createURI("six"));
+
+ AbstractQueryBuilder<?> builder = whereClause
+ .addOptional(List.of(first, second));
+
+ ElementPathBlock epb = new ElementPathBlock();
+ ElementOptional optional = new ElementOptional(epb);
+ epb.addTriplePath(first);
+ epb.addTriplePath(second);
+
+ WhereValidator visitor = new WhereValidator(optional);
+ builder.build().getQueryPattern().visit(visitor);
+ assertTrue(visitor.matching);
+ }
+
@ContractTest
public void testAddOptionalObjectsWithPath() {
WhereClause<?> whereClause = getProducer().newInstance();
@@ -275,7 +393,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
}
@ContractTest
- public void testAddFilter() throws ParseException {
+ public void testAddFilter() {
WhereClause<?> whereClause = getProducer().newInstance();
AbstractQueryBuilder<?> builder = whereClause.addFilter("?one<10");
@@ -437,7 +555,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
}
@ContractTest
- public void testSetVarsInFilter() throws ParseException {
+ public void testSetVarsInFilter() {
WhereClause<?> whereClause = getProducer().newInstance();
AbstractQueryBuilder<?> builder = whereClause.addFilter("?one < ?v");
@@ -697,7 +815,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
}
@ContractTest
- public void testBindStringVar() throws ParseException {
+ public void testBindStringVar() {
Var v = Var.alloc("foo");
WhereClause<?> whereClause = getProducer().newInstance();
AbstractQueryBuilder<?> builder = whereClause.addBind("rand()", v);
@@ -719,7 +837,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
}
@ContractTest
- public void testBindStringVar_Node_Variable() throws ParseException {
+ public void testBindStringVar_Node_Variable() {
Node v = NodeFactory.createVariable("foo");
WhereClause<?> whereClause = getProducer().newInstance();
AbstractQueryBuilder<?> builder = whereClause.addBind("rand()", v);
@@ -780,6 +898,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
}
+ @SuppressWarnings("deprecation")
@ContractTest
public void testList() {
WhereClause<?> whereClause = getProducer().newInstance();
@@ -832,7 +951,25 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
}
@ContractTest
- public void testAddGraph_frontsTriple() {
+ public void testAddGraphAbstractQueryBuilder() {
+ WhereClause<?> whereClause = getProducer().newInstance();
+ TriplePath tp = new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three")));
+
+ TestAbstractQueryBuilder abstractQueryBuilder = new TestAbstractQueryBuilder();
+ abstractQueryBuilder.getHandlerBlock().getWhereHandler().addWhere(tp);
+ AbstractQueryBuilder<?> builder = whereClause.addGraph( "<g>", abstractQueryBuilder);
+
+ ElementPathBlock epb = new ElementPathBlock();
+ ElementNamedGraph eng = new ElementNamedGraph(NodeFactory.createURI("g"), epb);
+
+ epb.addTriplePath(tp);
+ WhereValidator visitor = new WhereValidator(eng);
+ builder.build().getQueryPattern().visit(visitor);
+ assertTrue(visitor.matching);
+ }
+
+ @ContractTest
+ public void testAddGraphFrontsTriple() {
final Node s = NodeFactory.createURI("s");
final Node p = NodeFactory.createURI("p");
final Node o = NodeFactory.createURI("o");
@@ -877,7 +1014,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
}
@ContractTest
- public void testAddGraph_triple() {
+ public void testAddGraphTriple() {
final Node s = NodeFactory.createURI("s");
final Node p = NodeFactory.createURI("p");
final Node o = NodeFactory.createURI("o");
@@ -896,7 +1033,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
}
@ContractTest
- public void testAddGraph_triplePath() {
+ public void testAddGraphTriplePath() {
final Node s = NodeFactory.createURI("s");
final Node p = NodeFactory.createURI("p");
final Node o = NodeFactory.createURI("o");
@@ -914,6 +1051,28 @@ public class WhereClauseTest<T extends WhereClause<?>> extends AbstractClauseTes
query.getQueryPattern().visit(visitor);
assertTrue(visitor.matching);
}
+
+ @ContractTest
+ public void testAddGraphTriplePathCollection() {
+ WhereClause<?> whereClause = getProducer().newInstance();
+ PrefixMapping pmap = new PrefixMappingImpl();
+ pmap.setNsPrefix("ts", "urn:test:");
+ Path path = PathParser.parse("ts:two/ts:dos", pmap);
+ TriplePath first = new TriplePath(NodeFactory.createURI("one"), path, NodeFactory.createURI("three"));
+ TriplePath second = new TriplePath(NodeFactory.createURI("for"), path, NodeFactory.createURI("six"));
+
+ AbstractQueryBuilder<?> builder = whereClause
+ .addGraph("<g>", List.of(first, second));
+
+ ElementPathBlock epb = new ElementPathBlock();
+ ElementNamedGraph eng = new ElementNamedGraph(NodeFactory.createURI("g"), epb);
+ epb.addTriplePath(first);
+ epb.addTriplePath(second);
+
+ WhereValidator visitor = new WhereValidator(eng);
+ builder.build().getQueryPattern().visit(visitor);
+ assertTrue(visitor.matching);
+ }
@ContractTest
public void testAddWhereValueVar_var() {
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/SolutionModifierHandlerTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/SolutionModifierHandlerTest.java
index 5154a5faf6..4b2d82ab4f 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/SolutionModifierHandlerTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/SolutionModifierHandlerTest.java
@@ -28,7 +28,6 @@ import org.apache.jena.query.Query;
import org.apache.jena.query.SortCondition;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.expr.E_Random;
-import org.apache.jena.sparql.lang.sparql_11.ParseException;
import org.junit.Before;
import org.junit.Test;
@@ -44,7 +43,7 @@ public class SolutionModifierHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testAddAll() throws ParseException {
+ public void testAddAll() {
SolutionModifierHandler solutionModifier2 = new SolutionModifierHandler(new Query());
solutionModifier2.addOrderBy(Var.alloc("orderBy"));
solutionModifier2.addGroupBy(Var.alloc("groupBy"));
@@ -63,7 +62,7 @@ public class SolutionModifierHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testAll() throws ParseException {
+ public void testAll() {
solutionModifier.addOrderBy(Var.alloc("orderBy"));
solutionModifier.addGroupBy(Var.alloc("groupBy"));
solutionModifier.addHaving("SUM(?lprice) > 10");
@@ -130,7 +129,7 @@ public class SolutionModifierHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testAddHavingString() throws ParseException {
+ public void testAddHavingString() {
solutionModifier.addHaving("?having<10");
assertContainsRegex(HAVING + OPEN_PAREN + var("having") + OPT_SPACE + LT + 10 + CLOSE_PAREN, query.toString());
@@ -141,7 +140,7 @@ public class SolutionModifierHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testAddHavingVar() throws ParseException {
+ public void testAddHavingVar() {
solutionModifier.addHaving(Var.alloc("foo"));
assertContainsRegex(HAVING + var("foo"), query.toString());
@@ -150,7 +149,7 @@ public class SolutionModifierHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testAddHavingExpr() throws ParseException {
+ public void testAddHavingExpr() {
solutionModifier.addHaving(new E_Random());
assertContainsRegex(HAVING + "rand" + OPEN_PAREN + CLOSE_PAREN, query.toString());
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java
index 908b5558bd..ffbb84f3f2 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java
@@ -32,6 +32,7 @@ import org.apache.jena.query.Query;
import org.apache.jena.rdf.model.ResourceFactory;
import org.apache.jena.shared.PrefixMapping;
import org.apache.jena.shared.impl.PrefixMappingImpl;
+import org.apache.jena.sparql.core.PathBlock;
import org.apache.jena.sparql.core.TriplePath;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.engine.binding.Binding;
@@ -41,7 +42,6 @@ import org.apache.jena.sparql.expr.E_Function;
import org.apache.jena.sparql.expr.E_LessThan;
import org.apache.jena.sparql.expr.E_Random;
import org.apache.jena.sparql.expr.aggregate.AggCount;
-import org.apache.jena.sparql.lang.sparql_11.ParseException;
import org.apache.jena.sparql.path.P_Link;
import org.apache.jena.sparql.path.Path;
import org.apache.jena.sparql.path.PathParser;
@@ -127,7 +127,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testAddWhereObjects() {
+ public void testAddWhere3Objects() {
handler.addWhere(
new TriplePath(Triple.create(NodeFactory.createURI("one"), ResourceFactory.createResource("two").asNode(),
ResourceFactory.createLangLiteral("three", "en-US").asNode())));
@@ -144,7 +144,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testAddWhereObjectsWithPath() {
+ public void testAddWhere3ObjectsWithPath() {
PrefixMapping pmap = new PrefixMappingImpl();
pmap.setNsPrefix("ts", "urn:test:");
Path path = PathParser.parse("ts:two/ts:dos", pmap);
@@ -161,46 +161,59 @@ public class WhereHandlerTest extends AbstractHandlerTest {
assertTrue(wv.matching);
}
-
+
@Test
- public void testAddWhereAnonymous() {
- handler.addWhere(new TriplePath(Triple.create(Node.ANY, RDF.first.asNode(), Node.ANY)));
+ public void testAddWhereCollection() {
+ PrefixMapping pmap = new PrefixMappingImpl();
+ pmap.setNsPrefix("ts", "urn:test:");
+ Path path = PathParser.parse("ts:two/ts:dos", pmap);
+
+ TriplePath[] expected = {
+ new TriplePath(Triple.create(Node.ANY, RDF.first.asNode(), Node.ANY)),
+ new TriplePath(Triple.create(NodeFactory.createURI("one"), ResourceFactory.createResource("two").asNode(),
+ ResourceFactory.createLangLiteral("three", "en-US").asNode())),
+ new TriplePath(NodeFactory.createURI("one"), path, ResourceFactory.createLangLiteral("three", "en-US").asNode())
+ };
+
+ handler.addWhere(Arrays.asList(expected));
handler.build();
- TriplePath tp = new TriplePath(Triple.create(Node.ANY, RDF.first.asNode(), Node.ANY));
ElementPathBlock epb = new ElementPathBlock();
- epb.addTriple(tp);
+ PathBlock pb = epb.getPattern();
+ Arrays.stream(expected).forEach(pb::add);
+
WhereValidator wv = new WhereValidator(epb);
query.getQueryPattern().visit(wv);
assertTrue(wv.matching);
-
}
@Test
- public void testAddOptionalStrings() {
- handler.addOptional(new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
- NodeFactory.createURI("three"))));
+ public void testAddWhereWithAnonymous() {
+ handler.addWhere(new TriplePath(Triple.create(Node.ANY, RDF.first.asNode(), Node.ANY)));
handler.build();
- TriplePath tp = new TriplePath(
- Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three")));
+ TriplePath tp = new TriplePath(Triple.create(Node.ANY, RDF.first.asNode(), Node.ANY));
ElementPathBlock epb = new ElementPathBlock();
epb.addTriple(tp);
- ElementOptional opt = new ElementOptional(epb);
- WhereValidator wv = new WhereValidator(opt);
+ WhereValidator wv = new WhereValidator(epb);
query.getQueryPattern().visit(wv);
assertTrue(wv.matching);
}
@Test
- public void testAddOptionalAnonymous() {
- handler.addOptional(new TriplePath(Triple.create(Node.ANY, RDF.first.asNode(), Node.ANY)));
+ public void testAddOptionalList() {
+ TriplePath[] expected = {
+ new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
+ NodeFactory.createURI("three"))),
+ new TriplePath(Triple.create(Node.ANY, RDF.first.asNode(), Node.ANY))
+ };
+
+ handler.addOptional(Arrays.asList(expected));
handler.build();
-
- TriplePath tp = new TriplePath(Triple.create(Node.ANY, RDF.first.asNode(), Node.ANY));
+
ElementPathBlock epb = new ElementPathBlock();
- epb.addTriple(tp);
+ Arrays.stream(expected).forEach(epb::addTriple);
ElementOptional opt = new ElementOptional(epb);
WhereValidator wv = new WhereValidator(opt);
query.getQueryPattern().visit(wv);
@@ -238,9 +251,10 @@ public class WhereHandlerTest extends AbstractHandlerTest {
@Test
public void testAddOptionalObjects() {
- handler.addOptional(
+
+ handler.addOptional(Arrays.asList(
new TriplePath(Triple.create(NodeFactory.createURI("one"), ResourceFactory.createResource("two").asNode(),
- ResourceFactory.createLangLiteral("three", "en-US").asNode())));
+ ResourceFactory.createLangLiteral("three", "en-US").asNode()))));
handler.build();
ElementPathBlock epb = new ElementPathBlock();
@@ -261,8 +275,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
pmap.setNsPrefix("ts", "urn:test:");
Path path = PathParser.parse("ts:two/ts:dos", pmap);
- handler.addOptional(new TriplePath(NodeFactory.createURI("one"), path,
- ResourceFactory.createLangLiteral("three", "en-US").asNode()));
+ handler.addOptional(Arrays.asList(new TriplePath(NodeFactory.createURI("one"), path,
+ ResourceFactory.createLangLiteral("three", "en-US").asNode())));
handler.build();
ElementPathBlock epb = new ElementPathBlock();
@@ -294,7 +308,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testAddFilter() throws ParseException {
+ public void testAddFilter() {
handler.addFilter("?one < 10");
handler.build();
@@ -306,7 +320,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testAddFilterWithNamespace() throws ParseException {
+ public void testAddFilterWithNamespace(){
query.setPrefix("afn", "http://jena.apache.org/ARQ/function#");
handler.addFilter("afn:namespace(?one) = 'foo'");
handler.build();
@@ -321,7 +335,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testAddFilterVarOnly() throws ParseException {
+ public void testAddFilterVarOnly() {
handler.addFilter("?one");
handler.build();
@@ -356,7 +370,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testAddSubQueryWithVarExpressions() throws ParseException {
+ public void testAddSubQueryWithVarExpressions() {
SelectBuilder sb = new SelectBuilder();
sb.addPrefix("pfx", "uri").addVar("count(*)", "?x").addWhere("<one>", "<two>", "three");
handler.addSubQuery(sb);
@@ -541,7 +555,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
}
@Test
- public void addGraph() {
+ public void testAddGraph() {
WhereHandler handler2 = new WhereHandler(new Query());
handler2.addWhere(new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
@@ -560,6 +574,27 @@ public class WhereHandlerTest extends AbstractHandlerTest {
handler.getQueryPattern().visit(visitor);
assertTrue(visitor.matching);
}
+
+ @Test
+ public void testAddGraphTriplePaths() {
+
+ TriplePath[] expected = {
+ new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
+ NodeFactory.createURI("three"))),
+ new TriplePath(Triple.create(NodeFactory.createURI("four"), NodeFactory.createURI("five"),
+ NodeFactory.createURI("six"))) };
+
+ handler.addGraph(NodeFactory.createURI("graph"), Arrays.asList(expected));
+ handler.build();
+
+ ElementPathBlock epb = new ElementPathBlock();
+ Arrays.stream(expected).forEach(epb::addTriple);
+ ElementNamedGraph eng = new ElementNamedGraph(NodeFactory.createURI("graph"), epb);
+
+ WhereValidator visitor = new WhereValidator(eng);
+ handler.getQueryPattern().visit(visitor);
+ assertTrue(visitor.matching);
+ }
@Test
public void testSetVarsInTriple() {
@@ -589,7 +624,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testSetVarsInFilter() throws ParseException {
+ public void testSetVarsInFilter() {
handler.addFilter("?one < ?v");
handler.build();
@@ -614,7 +649,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
@Test
public void testSetVarsInOptional() {
Var v = Var.alloc("v");
- handler.addOptional(new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"), v)));
+ handler.addOptional(Arrays.asList(new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"), v))));
handler.build();
TriplePath tp = new TriplePath(Triple.create(NodeFactory.createURI("one"), NodeFactory.createURI("two"), v));
@@ -720,7 +755,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
}
@Test
- public void testBindStringVar() throws ParseException {
+ public void testBindStringVar() {
Var v = Var.alloc("foo");
handler.addBind("rand()", v);
handler.build();
@@ -744,6 +779,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
assertTrue(visitor.matching);
}
+ @SuppressWarnings("deprecation")
@Test
public void testList() {
Node n = handler.list("<one>", "?var", "'three'");
@@ -771,6 +807,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
assertTrue(n.isBlank());
}
+ @SuppressWarnings("deprecation")
@Test
public void testListInTriple() {
handler.addWhere(new TriplePath(Triple.create(handler.list("<one>", "?var", "'three'"),