This is an automated email from the ASF dual-hosted git repository.
claude pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jena.git
The following commit(s) were added to refs/heads/master by this push:
new 2843086 WIP: 1805 fix (#659)
2843086 is described below
commit 284308663ce995d18cad1e009a0b8975a98fd65d
Author: Claude Warren <[email protected]>
AuthorDate: Sat Dec 21 13:09:00 2019 +0000
WIP: 1805 fix (#659)
* Added addWhere( AbstractQueryBuilder )
* simplified code
* updated javadoc
* removed unused imports
* updated javadoc
* Added addPrefixes(PrefixMapping prefixes)
* updated javadoc
* Added appPrefixes(PrefixMapping) test + cleaned up tests
* changed to follow jena version
* Example of StreamRDF to RDFConnection
* added addInsertQuads() and addDeleteQuads()
* updated javadocs
* Removed unused imports
* Added license.
* reorganized POM file
---
jena-examples/pom.xml | 22 +--
.../example/streaming/StreamRDFToConnection.java | 147 +++++++++++++++++++++
.../arq/querybuilder/AbstractQueryBuilder.java | 7 +
.../apache/jena/arq/querybuilder/ExprFactory.java | 9 ++
.../jena/arq/querybuilder/UpdateBuilder.java | 94 ++++++++++---
.../arq/querybuilder/clauses/PrologClause.java | 12 +-
.../updatebuilder/CollectionQuadHolder.java | 10 +-
.../updatebuilder/QuadCollectionHolder.java | 102 ++++++++++++++
.../jena/arq/querybuilder/UpdateBuilderTest.java | 69 ++++++++++
.../arq/querybuilder/clauses/PrologClauseTest.java | 73 ++++++----
10 files changed, 482 insertions(+), 63 deletions(-)
diff --git a/jena-examples/pom.xml b/jena-examples/pom.xml
index 7c444ba..2c7c57d 100644
--- a/jena-examples/pom.xml
+++ b/jena-examples/pom.xml
@@ -19,11 +19,15 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.jena</groupId>
+ <artifactId>jena</artifactId>
+ <version>3.14.0-SNAPSHOT</version>
+ </parent>
- <groupId>org.apache.jena</groupId>
+ <modelVersion>4.0.0</modelVersion>
+
<artifactId>jena-examples</artifactId>
- <version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Apache Jena - Code Examples</name>
@@ -31,7 +35,6 @@
<url>https://jena.apache.org/</url>
<properties>
- <ver.jena>[3.1.0,)</ver.jena>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
@@ -44,20 +47,21 @@
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>apache-jena-libs</artifactId>
- <version>${ver.jena}</version>
<type>pom</type>
+ <version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- <version>4.10</version>
- <type>jar</type>
- <scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
- <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jena</groupId>
+ <artifactId>jena-querybuilder</artifactId>
+ <version>${project.version}</version>
</dependency>
</dependencies>
diff --git
a/jena-examples/src/main/java/org/apache/jena/example/streaming/StreamRDFToConnection.java
b/jena-examples/src/main/java/org/apache/jena/example/streaming/StreamRDFToConnection.java
new file mode 100644
index 0000000..1cb9eb4
--- /dev/null
+++
b/jena-examples/src/main/java/org/apache/jena/example/streaming/StreamRDFToConnection.java
@@ -0,0 +1,147 @@
+/*
+ * 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.example.streaming;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.jena.arq.querybuilder.UpdateBuilder;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.query.Dataset;
+import org.apache.jena.query.DatasetFactory;
+import org.apache.jena.query.TxnType;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.rdf.model.Property;
+import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.rdf.model.ResourceFactory;
+import org.apache.jena.rdf.model.Statement;
+import org.apache.jena.rdf.model.impl.StatementImpl;
+import org.apache.jena.rdfconnection.RDFConnection;
+import org.apache.jena.rdfconnection.RDFConnectionFactory;
+import org.apache.jena.riot.system.StreamRDF;
+import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.vocabulary.RDF;
+
+/**
+ * Example of how to implement a StreamRDF that caches and writes to
+ * an RDFConnection.
+ *
+ */
+public class StreamRDFToConnection implements StreamRDF {
+ private RDFConnection connection;
+ private int bufferSize = 1000;
+ private Set<Quad> quads = new HashSet<Quad>();
+ private Model model =
ModelFactory.createMemModelMaker().createFreshModel();
+
+ /**
+ * Constructs the StreamRDFToConnection using default 1000 quad buffer
size.
+ * @param connection the connection to talk to.
+ */
+ public StreamRDFToConnection( RDFConnection connection ) {
+ this.connection = connection;
+ }
+
+ /**
+ * Constructs the StreamRDFToConnection with the specified buffer size
+ * @param connection the connection to talk to.
+ * @param bufferSize the buffersize.
+ */
+ public StreamRDFToConnection( RDFConnection connection, int bufferSize
) {
+ this.connection = connection;
+ this.bufferSize = bufferSize;
+ }
+
+ /**
+ * See if we should flush the buffer.
+ */
+ private void isBufferFull() {
+ if (model.size() + quads.size() >= bufferSize)
+ {
+ flush();
+ }
+ }
+
+ /**
+ * Flushes the buffer to the connection.
+ */
+ private void flush() {
+ UpdateBuilder builder = new UpdateBuilder();
+ builder.addPrefixes( model );
+ builder.addInsert( model );
+ builder.addInsertQuads( quads );
+ connection.begin( TxnType.WRITE );
+ connection.update( builder.build() );
+ connection.commit();
+ model.removeAll();
+ quads.clear();
+ }
+
+ @Override
+ public void start() {
+ // does nothing.
+ }
+ @Override
+ public void triple(Triple triple) {
+ model.add( model.asStatement(triple));
+ isBufferFull();
+ }
+ @Override
+ public void quad(Quad quad) {
+ quads.add(quad);
+ isBufferFull();
+ }
+ @Override
+ public void base(String base) {
+ // do nothing
+ }
+ @Override
+ public void prefix(String prefix, String iri) {
+ model.setNsPrefix(prefix, iri);
+ }
+ @Override
+ public void finish() {
+ flush();
+ }
+
+ public static void main(String [] args) {
+ Dataset dataset = DatasetFactory.create();
+ RDFConnection connection =
RDFConnectionFactory.connect(dataset);
+ StreamRDFToConnection stream = new StreamRDFToConnection(
connection );
+
+ Resource s = ResourceFactory.createResource( "s" );
+ Property p = ResourceFactory.createProperty( "p" );
+ RDFNode o = ResourceFactory.createPlainLiteral("OHHHH");
+ Resource t = ResourceFactory.createResource( "t" );
+ Resource g = ResourceFactory.createResource( "g" );
+ Statement stmt1 = new StatementImpl( s, p ,o );
+ Statement stmt2 = new StatementImpl( s, RDF.type, t );
+ stream.start();
+ stream.triple( stmt1.asTriple() );
+ stream.quad( new Quad( g.asNode(), stmt2.asTriple()));
+ stream.finish();
+
+ System.out.println( "Contains model 'g':
"+dataset.containsNamedModel("g") );
+ Model m = dataset.getDefaultModel();
+ System.out.println( "Default model contains <s,p,o>: "+
m.contains( stmt1 ));
+ m = dataset.getNamedModel( "g" );
+ System.out.println( "model 'g' contains <s,RDF.type,t>: "+
m.contains( stmt2 ));
+
+ }
+}
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 6a261b9..28d8f4b 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
@@ -444,6 +444,13 @@ implements Cloneable, PrologClause<T>, ValuesClause<T> {
getPrologHandler().addPrefixes(prefixes);
return (T) this;
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public T addPrefixes(PrefixMapping prefixMapping) {
+ getPrologHandler().addPrefixes( prefixMapping );
+ return (T) this;
+ }
@SuppressWarnings("unchecked")
@Override
diff --git
a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ExprFactory.java
b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ExprFactory.java
index ef2e5a2..dec89e1 100644
---
a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ExprFactory.java
+++
b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ExprFactory.java
@@ -121,10 +121,19 @@ public class ExprFactory {
private final PrefixMapping pMap;
+ /**
+ * Constructs an expression factor with the specified prefix
definitions.
+ * @param pMap the PrefixMapping to use in the expressions.
+ */
public ExprFactory(PrefixMapping pMap) {
this.pMap = pMap;
}
+ /**
+ * Constructs an expression factory with the prefix definitions found in
+ * {@code PrefixMapping.Extended}
+ * @see PrefixMapping#Extended
+ */
public ExprFactory() {
this(PrefixMapping.Extended);
}
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 66569db..272a807 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
@@ -33,6 +33,7 @@ import
org.apache.jena.arq.querybuilder.updatebuilder.CollectionQuadHolder;
import org.apache.jena.arq.querybuilder.updatebuilder.ModelQuadHolder;
import org.apache.jena.arq.querybuilder.updatebuilder.PrefixHandler;
import org.apache.jena.arq.querybuilder.updatebuilder.QBQuadHolder;
+import org.apache.jena.arq.querybuilder.updatebuilder.QuadCollectionHolder;
import org.apache.jena.arq.querybuilder.updatebuilder.QuadHolder;
import org.apache.jena.arq.querybuilder.updatebuilder.SingleQuadHolder;
import org.apache.jena.arq.querybuilder.updatebuilder.WhereQuadHolder;
@@ -76,7 +77,7 @@ public class UpdateBuilder {
private Node with;
/**
- * Constructor.
+ * Creates an UpdateBuilder with an empty prefix mapping.
*/
public UpdateBuilder() {
this.prefixHandler = new PrefixHandler();
@@ -86,7 +87,8 @@ public class UpdateBuilder {
}
/**
- * Constructor. Uses the prefixes from the prolog clause. <b>May modify
the
+ * Creates an UpdateBuilder with the prefixes defined in the prolog
clause.
+ * <b>May modify the
* contents of the prefix mapping in the prolog handler</b>
*
* @param prologClause
@@ -97,8 +99,8 @@ public class UpdateBuilder {
}
/**
- * Constructor. Uses the specified prefix mapping. <b>May modify the
- * contents of the prefix mapping</b>
+ * Creates an UpdateBuilder with the specified PrefixMapping.
+ * <b>May modify the contents of the prefix mapping</b>
*
* @param pMap
* the prefix mapping to use.
@@ -108,7 +110,11 @@ public class UpdateBuilder {
this.whereProcessor = new WhereQuadHolder(prefixHandler);
}
- // conver a collection of QuadHolder to an iterator on quads.
+ /**
+ * Convert a collection of QuadHolder to an iterator on Quads.
+ * @param holders the Collection of QuadHolder objects
+ * @return an iterator over the Quads.
+ */
private ExtendedIterator<Quad> getQuads(Collection<QuadHolder> holders)
{
ExtendedIterator<Quad> result = NiceIterator.emptyIterator();
for (QuadHolder holder : holders) {
@@ -192,12 +198,6 @@ public class UpdateBuilder {
// build updates with where clauses
private Update buildWhere() {
- // if (inserts.isEmpty()) {
- // QuadAcc quadAcc = new QuadAcc(getQuads(deletes).toList());
- // UpdateDeleteWhere retval = new UpdateDeleteWhere(quadAcc);
- // return retval;
- // }
-
UpdateModify retval = new UpdateModify();
if (with != null)
{
@@ -400,6 +400,7 @@ public class UpdateBuilder {
/**
* Add all the statements in the model to the insert statement.
+ * Uses Quad.defaultGraphNodeGenerated as the graph name.
*
* @param model The model to insert.
* @return this builder for chaining.
@@ -410,10 +411,12 @@ public class UpdateBuilder {
}
/**
- * Add all the statements in the model to the insert statement.
+ * Add all the triples in the model to the insert statement.
+ * Uses Quad.defaultGraphNodeGenerated as the graph name.
*
* @param collection The triples to insert.
* @return this builder for chaining.
+ * @see Quad#defaultGraphNodeGenerated
*/
public UpdateBuilder addInsert(Collection<Triple> collection) {
inserts.add(new CollectionQuadHolder( collection ));
@@ -421,10 +424,23 @@ public class UpdateBuilder {
}
/**
- * Add all the statements in the model to the insert statement.
+ * Add all the quads in the collection to the insert statement.
+ *
+ * @param collection The quads to insert.
+ * @return this builder for chaining.
+ */
+ public UpdateBuilder addInsertQuads(Collection<Quad> collection) {
+ inserts.add(new QuadCollectionHolder( collection ));
+ return this;
+ }
+
+ /**
+ * Add all the triples to the insert statement.
+ * Uses Quad.defaultGraphNodeGenerated as the graph name.
*
* @param iter The iterator of triples to insert.
* @return this builder for chaining.
+ * @see Quad#defaultGraphNodeGenerated
*/
public UpdateBuilder addInsert(Iterator<Triple> iter) {
inserts.add(new CollectionQuadHolder( iter ));
@@ -451,8 +467,9 @@ public class UpdateBuilder {
}
/**
- * Add all the statements in the model to the insert statement.
+ * Add triples to the insert statement.
*
+ * @param g the name of the graph to add the triples to.
* @param collection The triples to insert.
* @return this builder for chaining.
*/
@@ -464,8 +481,8 @@ public class UpdateBuilder {
}
/**
- * Add all the statements in the model to the insert statement.
- *
+ * Add triples to the insert statement.
+ * @param g the name of the graph to add the triples to.
* @param iter The iterator of triples to insert.
* @return this builder for chaining.
*/
@@ -479,8 +496,9 @@ public class UpdateBuilder {
/**
* Add the statements from the where clause in the specified query
builder
* to the insert statement.
- *
+ * Uses Quad.defaultGraphNodeGenerated as the graph name.
* @see #makeNode(Object)
+ * @see Quad#defaultGraphNodeGenerated
* @param queryBuilder
* The query builder to extract the where clause from.
* @return this builder for chaining.
@@ -534,7 +552,6 @@ public class UpdateBuilder {
/**
* Add a quad to the delete statement.
*
- *
* @param quad
* the quad to add.
* @return this builder for chaining.
@@ -543,6 +560,17 @@ public class UpdateBuilder {
deletes.add(new SingleQuadHolder(quad));
return this;
}
+
+ /**
+ * Add all the quads collection to the delete statement.
+ *
+ * @param collection The quads to insert.
+ * @return this builder for chaining.
+ */
+ public UpdateBuilder addDeleteQuads(Collection<Quad> collection) {
+ deletes.add(new QuadCollectionHolder( collection ));
+ return this;
+ }
/**
* Add a triple to the delete statement.
@@ -567,11 +595,12 @@ public class UpdateBuilder {
/**
* Add a triple to the delete statement.
- *
+ * Uses Quad.defaultGraphNodeGenerated as the graph name.
*
* @param t
* the triple to add.
* @return this builder for chaining.
+ * @see Quad#defaultGraphNodeGenerated
*/
public UpdateBuilder addDelete(Triple t) {
deletes.add(new SingleQuadHolder(t));
@@ -579,7 +608,7 @@ public class UpdateBuilder {
}
/**
- * Add a triple in a specified graph to the delete statement.
+ * Add a triple to the delete statement.
*
* The graph object is converted by a call to makeNode().
*
@@ -598,9 +627,11 @@ public class UpdateBuilder {
/**
* Add all the statements in the model to the delete statement.
+ * Uses Quad.defaultGraphNodeGenerated as the graph name.
*
* @param model The model to insert.
* @return this builder for chaining.
+ * @see Quad#defaultGraphNodeGenerated
*/
public UpdateBuilder addDelete(Model model) {
deletes.add(new ModelQuadHolder( model ));
@@ -608,10 +639,12 @@ public class UpdateBuilder {
}
/**
- * Add all the statements in the model to the delete statement.
+ * Add all triples to the delete statement.
+ * Uses Quad.defaultGraphNodeGenerated as the graph name.
*
* @param collection The collection of triples to insert.
* @return this builder for chaining.
+ * @see Quad#defaultGraphNodeGenerated
*/
public UpdateBuilder addDelete(Collection<Triple> collection) {
deletes.add(new CollectionQuadHolder( collection ));
@@ -619,10 +652,12 @@ public class UpdateBuilder {
}
/**
- * Add all the statements in the model to the delete statement.
+ * Add all the triples in the iterator to the delete statement.
+ * Uses Quad.defaultGraphNodeGenerated as the graph name.
*
* @param iter The iterator of triples to insert.
* @return this builder for chaining.
+ * @see Quad#defaultGraphNodeGenerated
*/
public UpdateBuilder addDelete(Iterator<Triple> iter) {
deletes.add(new CollectionQuadHolder( iter ));
@@ -682,8 +717,10 @@ public class UpdateBuilder {
/**
* Add the statements from the where clause in the specified query
builder
* to the delete statement.
+ * Uses Quad.defaultGraphNodeGenerated as the graph name.
*
* @see #makeNode(Object)
+ * @see Quad#defaultGraphNodeGenerated
* @param queryBuilder
* The query builder to extract the where clause from.
* @return this builder for chaining.
@@ -763,6 +800,19 @@ public class UpdateBuilder {
prefixHandler.addPrefixes(prefixes);
return this;
}
+
+ /**
+ * Add the prefixes to the prefix mapping.
+ *
+ * @param prefixes
+ * the prefix mapping to add.
+ * @return this builder for chaining
+ */
+
+ public UpdateBuilder addPrefixes(PrefixMapping prefixes) {
+ prefixHandler.addPrefixes(prefixes);
+ return this;
+ }
/**
* Get an ExprFactory that uses the prefixes from this builder.
diff --git
a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/PrologClause.java
b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/PrologClause.java
index 79d51a5..ac2d54f 100644
---
a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/PrologClause.java
+++
b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/PrologClause.java
@@ -24,6 +24,7 @@ import org.apache.jena.arq.querybuilder.ExprFactory;
import org.apache.jena.arq.querybuilder.handlers.PrologHandler;
import org.apache.jena.graph.Node ;
import org.apache.jena.rdf.model.Resource ;
+import org.apache.jena.shared.PrefixMapping;
/**
* Interface that defines the PrologClause as per
@@ -80,7 +81,7 @@ public interface PrologClause<T extends
AbstractQueryBuilder<T>> {
public T addPrefix(String pfx, String uri);
/**
- * Adds a prefix.
+ * Adds prefixes.
*
* @param prefixes
* A mapping of prefix to URI to add.
@@ -89,6 +90,15 @@ public interface PrologClause<T extends
AbstractQueryBuilder<T>> {
public T addPrefixes(Map<String, String> prefixes);
/**
+ * Adds prefixes.
+ *
+ * @param prefixes
+ * A PrefixMapping instance..
+ * @return This builder for chaining.
+ */
+ public T addPrefixes(PrefixMapping prefixes);
+
+ /**
* Sets the base URI.
*
* See {@link AbstractQueryBuilder#makeNode} for conversion of the uri
param. The resulting Node
diff --git
a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/CollectionQuadHolder.java
b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/CollectionQuadHolder.java
index 10cc511..d9aaea7 100644
---
a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/CollectionQuadHolder.java
+++
b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/CollectionQuadHolder.java
@@ -36,7 +36,6 @@ import org.apache.jena.util.iterator.WrappedIterator;
*
*/
public class CollectionQuadHolder implements QuadHolder {
-
private final Set<Triple> collection;
private final Node defaultGraphName;
private Map<Var, Node> values;
@@ -64,7 +63,8 @@ public class CollectionQuadHolder implements QuadHolder {
* the iterator of triples.
*/
public CollectionQuadHolder(final Node graph, Iterator<Triple> triples) {
- this.collection = WrappedIterator.create( triples ).toSet();
+ this.collection = new HashSet<Triple>();
+ triples.forEachRemaining( this.collection::add );
defaultGraphName = graph;
}
@@ -85,9 +85,8 @@ public class CollectionQuadHolder implements QuadHolder {
* @param triples
* the iterator of triples.
*/
- public CollectionQuadHolder(Iterator<Triple> triples) {
- this.collection = WrappedIterator.create( triples ).toSet();
- defaultGraphName = Quad.defaultGraphNodeGenerated;
+ public CollectionQuadHolder(final Iterator<Triple> triples) {
+ this( Quad.defaultGraphNodeGenerated, triples );
}
private Node valueMap( Node n )
@@ -125,5 +124,4 @@ public class CollectionQuadHolder implements QuadHolder {
this.values = values;
return this;
}
-
}
diff --git
a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QuadCollectionHolder.java
b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QuadCollectionHolder.java
new file mode 100644
index 0000000..67f9687
--- /dev/null
+++
b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QuadCollectionHolder.java
@@ -0,0 +1,102 @@
+/*
+ * 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.querybuilder.updatebuilder;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.util.iterator.ExtendedIterator;
+import org.apache.jena.util.iterator.WrappedIterator;
+
+/**
+ * An QuadHolder that contains Quads from a collection or iterator..
+ *
+ */
+public class QuadCollectionHolder implements QuadHolder {
+
+ private final Set<Quad> collection;
+ private Map<Var, Node> values;
+
+ /**
+ * Constructor.
+ *
+ * @param quads
+ * the collection of quads.
+ */
+ public QuadCollectionHolder( final Collection<Quad> quads) {
+ this.collection = new HashSet<Quad>();
+ this.collection.addAll( quads );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param quads
+ * the collection of quads.
+ */
+ public QuadCollectionHolder( final Iterator<Quad> quads) {
+ this.collection = new HashSet<Quad>();
+ quads.forEachRemaining( collection::add );
+ }
+
+ private Node valueMap( Node n )
+ {
+ if (n.isVariable())
+ {
+ Var v = Var.alloc(n);
+ return values.getOrDefault(v, n);
+ }
+ return n;
+ }
+
+ @Override
+ public ExtendedIterator<Quad> getQuads() {
+ ExtendedIterator<Quad> retval =
+ WrappedIterator.create( collection.iterator() );
+
+ if (values != null)
+ {
+ retval = retval.mapWith( q -> new Quad(
+ valueMap(q.getGraph()),
+ valueMap(q.getSubject()),
+ valueMap(q.getPredicate()),
+ valueMap(q.getObject())
+ ));
+ }
+ return retval;
+ }
+
+
+
+ /**
+ * This implementation does nothing.
+ */
+ @Override
+ public QuadHolder setValues(final Map<Var, Node> values) {
+ this.values = values;
+ return this;
+ }
+
+
+}
diff --git
a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java
b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java
index 0f3f654..4e373e1 100644
---
a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java
+++
b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java
@@ -20,6 +20,7 @@ package org.apache.jena.arq.querybuilder;
import static org.junit.Assert.*;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import org.apache.jena.arq.querybuilder.UpdateBuilder;
@@ -145,6 +146,40 @@ public class UpdateBuilderTest {
}
@Test
+ public void testInsert_QuadCollection()
+ {
+ UpdateBuilder builder = new UpdateBuilder();
+ Collection<Quad> quads = new ArrayList<Quad>();
+
+ quads.add( new Quad( g, s, p, o) );
+
+ Node g2 = NodeFactory.createURI("http://example.com/graph2");
+ Node s2 = NodeFactory.createURI("http://example.com/subject2");
+ Node p2 =
NodeFactory.createURI("http://example.com/predicate2");
+ Node o2 = NodeFactory.createURI("http://example.com/object2");
+
+ quads.add( new Quad( g2, s2, p2, o2) );
+
+ builder.addInsertQuads(quads);
+ Update update = builder.build();
+ assertTrue( update instanceof UpdateDataInsert);
+ UpdateDataInsert udi = (UpdateDataInsert)update;
+ List<Quad> quads2 = udi.getQuads();
+ assertEquals( 2, quads2.size());
+ Quad q = quads2.get(0);
+ assertEquals( g, q.getGraph());
+ assertEquals( s, q.getSubject());
+ assertEquals( p, q.getPredicate());
+ assertEquals( o, q.getObject());
+
+ q = quads2.get(1);
+ assertEquals( g2, q.getGraph());
+ assertEquals( s2, q.getSubject());
+ assertEquals( p2, q.getPredicate());
+ assertEquals( o2, q.getObject());
+ }
+
+ @Test
public void testInsertValueReplacement()
{
Var v = Var.alloc("v");
@@ -251,6 +286,40 @@ public class UpdateBuilderTest {
assertEquals( p, q.getPredicate());
assertEquals( o, q.getObject());
}
+
+ @Test
+ public void testDelete_QuadCollection()
+ {
+ UpdateBuilder builder = new UpdateBuilder();
+ Collection<Quad> quads = new ArrayList<Quad>();
+
+ quads.add( new Quad( g, s, p, o) );
+
+ Node g2 = NodeFactory.createURI("http://example.com/graph2");
+ Node s2 = NodeFactory.createURI("http://example.com/subject2");
+ Node p2 =
NodeFactory.createURI("http://example.com/predicate2");
+ Node o2 = NodeFactory.createURI("http://example.com/object2");
+
+ quads.add( new Quad( g2, s2, p2, o2) );
+
+ builder.addDeleteQuads(quads);
+ Update update = builder.build();
+ assertTrue( update instanceof UpdateDataDelete);
+ UpdateDataDelete udd = (UpdateDataDelete)update;
+ List<Quad> quads2 = udd.getQuads();
+ assertEquals( 2, quads2.size());
+ Quad q = quads2.get(0);
+ assertEquals( g, q.getGraph());
+ assertEquals( s, q.getSubject());
+ assertEquals( p, q.getPredicate());
+ assertEquals( o, q.getObject());
+
+ q = quads2.get(1);
+ assertEquals( g2, q.getGraph());
+ assertEquals( s2, q.getSubject());
+ assertEquals( p2, q.getPredicate());
+ assertEquals( o2, q.getObject());
+ }
@Test
public void testDeleteValueReplacement()
diff --git
a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/PrologClauseTest.java
b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/PrologClauseTest.java
index 758108c..8abf6d8 100644
---
a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/PrologClauseTest.java
+++
b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/PrologClauseTest.java
@@ -26,15 +26,17 @@ import
org.apache.jena.arq.querybuilder.AbstractQueryBuilder;
import org.apache.jena.arq.querybuilder.clauses.PrologClause;
import org.apache.jena.arq.querybuilder.handlers.PrologHandler;
import org.apache.jena.graph.NodeFactory ;
+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.junit.After;
import org.xenei.junit.contract.Contract;
import org.xenei.junit.contract.ContractTest;
import org.xenei.junit.contract.IProducer;
@Contract(PrologClause.class)
-public class PrologClauseTest<T extends PrologClause<?>> extends
- AbstractClauseTest {
+public class PrologClauseTest<T extends PrologClause<?>> {
// the producer we will user
private IProducer<T> producer;
@@ -66,9 +68,10 @@ public class PrologClauseTest<T extends PrologClause<?>>
extends
PrologClause<?> prologClause = getProducer().newInstance();
AbstractQueryBuilder<?> builder = prologClause.addPrefix("pfx",
ResourceFactory.createResource("uri"));
-
- String[] s = byLine(builder);
- assertContainsRegex("PREFIX\\s+pfx:\\s+\\<uri\\>", s);
+ Query q = builder.build();
+ PrefixMapping map = q.getPrefixMapping();
+ assertEquals( "uri", map.getNsPrefixURI("pfx"));
+ assertEquals( 1, map.getNsPrefixMap().size() );
}
@ContractTest
@@ -77,39 +80,59 @@ public class PrologClauseTest<T extends PrologClause<?>>
extends
AbstractQueryBuilder<?> builder = prologClause.addPrefix("pfx",
NodeFactory.createURI("uri"));
- String[] s = byLine(builder);
- assertContainsRegex("PREFIX\\s+pfx:\\s+\\<uri\\>", s);
+ Query q = builder.build();
+ PrefixMapping map = q.getPrefixMapping();
+ assertEquals( "uri", map.getNsPrefixURI("pfx"));
+ assertEquals( 1, map.getNsPrefixMap().size() );
}
@ContractTest
public void testAddPrefixString() {
PrologClause<?> prologClause = getProducer().newInstance();
AbstractQueryBuilder<?> builder = prologClause.addPrefix("pfx",
"uri");
-
- String[] s = byLine(builder);
- assertContainsRegex("PREFIX\\s+pfx:\\s+\\<uri\\>", s);
+ Query q = builder.build();
+ PrefixMapping map = q.getPrefixMapping();
+ assertEquals( "uri", map.getNsPrefixURI("pfx"));
+ assertEquals( 1, map.getNsPrefixMap().size() );
}
@ContractTest
- public void testAddPrefixes() {
+ public void testAddPrefixes_Map() {
Map<String, String> map = new HashMap<>();
map.put("pfx", "uri");
map.put("pfx2", "uri2");
PrologClause<?> prologClause = getProducer().newInstance();
AbstractQueryBuilder<?> builder = prologClause.addPrefixes(map);
- String[] s = byLine(builder);
- assertContainsRegex("PREFIX\\s+pfx:\\s+\\<uri\\>", s);
- assertContainsRegex("PREFIX\\s+pfx2:\\s+\\<uri2\\>", s);
+ Query q = builder.build();
+ PrefixMapping map2 = q.getPrefixMapping();
+ assertEquals( "uri", map2.getNsPrefixURI("pfx"));
+ assertEquals( "uri2", map2.getNsPrefixURI("pfx2"));
+ assertEquals( 2, map2.getNsPrefixMap().size() );
+ }
+
+ @ContractTest
+ public void testAddPrefixes_PrefixMapping() {
+ PrefixMapping map = new PrefixMappingImpl();
+ map.setNsPrefix("pfx", "uri");
+ map.setNsPrefix("pfx2", "uri2");
+ PrologClause<?> prologClause = getProducer().newInstance();
+ AbstractQueryBuilder<?> builder = prologClause.addPrefixes(map);
+ Query q = builder.build();
+ PrefixMapping map2 = q.getPrefixMapping();
+ assertEquals( map.getNsPrefixURI("pfx"),
map2.getNsPrefixURI("pfx"));
+ assertEquals( map.getNsPrefixURI("pfx2"),
map2.getNsPrefixURI("pfx2"));
+ assertEquals( 2, map2.getNsPrefixMap().size() );
}
+
@ContractTest
public void testSetBaseResource() {
PrologClause<?> prologClause = getProducer().newInstance();
AbstractQueryBuilder<?> builder =
prologClause.setBase(ResourceFactory
.createResource("http://example.com/uri"));
- String[] s = byLine(builder);
- assertContainsRegex("BASE\\s+\\<http://example\\.com/uri\\>",
s);
+ Query q = builder.build();
+ assertEquals( "http://example.com/uri",
q.getResolver().getBaseIRIasString());
}
@ContractTest
@@ -118,27 +141,27 @@ public class PrologClauseTest<T extends PrologClause<?>>
extends
AbstractQueryBuilder<?> builder =
prologClause.setBase(NodeFactory
.createURI("http://example.com/uri"));
- String[] s = byLine(builder);
- assertContainsRegex("BASE\\s+\\<http://example\\.com/uri\\>",
s);
+ Query q = builder.build();
+ assertEquals( "http://example.com/uri",
q.getResolver().getBaseIRIasString());
}
@ContractTest
public void testSetBaseString() {
PrologClause<?> prologClause = getProducer().newInstance();
- AbstractQueryBuilder<?> builder = prologClause.setBase("uri");
+ AbstractQueryBuilder<?> builder =
prologClause.setBase("http://example.com/uri");
- String[] s = byLine(builder);
- assertContainsRegex("BASE\\s+\\<file:\\S+/uri\\>", s);
+ Query q = builder.build();
+ assertEquals( "http://example.com/uri",
q.getResolver().getBaseIRIasString());
}
@ContractTest
public void testSetBaseTwice() {
PrologClause<?> prologClause = getProducer().newInstance();
- prologClause.setBase("uri");
- AbstractQueryBuilder<?> builder = prologClause.setBase("uri2");
+ prologClause.setBase("http://example.com/uri");
+ AbstractQueryBuilder<?> builder =
prologClause.setBase("http://example.com/uri2");
- String[] s = byLine(builder);
- assertContainsRegex("BASE\\s+\\<file:\\S+/uri2\\>", s);
+ Query q = builder.build();
+ assertEquals( "http://example.com/uri2",
q.getResolver().getBaseIRIasString());
}
}