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 2017/06/04 11:39:22 UTC

[1/6] jena git commit: Initial implementation with tests

Repository: jena
Updated Branches:
  refs/heads/master e79199a7a -> bd357d406


http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderExampleTests.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderExampleTests.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderExampleTests.java
new file mode 100644
index 0000000..894a98f
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderExampleTests.java
@@ -0,0 +1,659 @@
+/*
+ * 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;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jena.arq.querybuilder.SelectBuilder;
+import org.apache.jena.arq.querybuilder.UpdateBuilder;
+import org.apache.jena.datatypes.xsd.XSDDatatype;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.graph.impl.CollectionGraph;
+import org.apache.jena.query.Dataset;
+import org.apache.jena.query.DatasetFactory;
+import org.apache.jena.rdf.model.Literal;
+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.sparql.vocabulary.FOAF;
+import org.apache.jena.update.UpdateAction;
+import org.apache.jena.update.UpdateRequest;
+import org.apache.jena.vocabulary.DCTypes;
+import org.apache.jena.vocabulary.DC_11;
+import org.apache.jena.vocabulary.RDF;
+import org.apache.jena.vocabulary.XSD;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests based on https://www.w3.org/TR/sparql11-update examples
+ * 
+ * Tests 13-15 are not implemented as the builder does not interface with them.
+ *
+ */
+public class UpdateBuilderExampleTests {
+
+	private static final String NS_prefix = "http://example.org/ns#";
+
+	private List<Triple> triples;
+	private Graph g;
+	private Model m;
+
+	public UpdateBuilderExampleTests() {
+		triples = new ArrayList<Triple>();
+		g = new CollectionGraph(triples);
+		m = ModelFactory.createModelForGraph(g);
+	}
+
+	@Before
+	public void setup() {
+		triples.clear();
+		m.clearNsPrefixMap();
+	}
+
+	/**
+	 * Example 1: Adding some triples to a graph
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_1
+	 */
+	@Test
+	public void example1() {
+		Resource r = ResourceFactory.createResource("http://example/book1");
+		Property price = ResourceFactory.createProperty(NS_prefix + "price");
+		Literal priceV = ResourceFactory.createPlainLiteral("42");
+		m.add(r, price, priceV);
+		m.setNsPrefix("dc", DC_11.NS);
+		m.setNsPrefix("ns", NS_prefix);
+
+		UpdateBuilder builder = new UpdateBuilder().addPrefix("dc", DC_11.NS).addInsert(r, DC_11.title, "A new book")
+				.addInsert(r, DC_11.creator, "A.N.Other");
+
+		UpdateAction.execute(builder.buildRequest(), m);
+
+		assertTrue(m.contains(r, price, priceV));
+		assertTrue(m.contains(r, DC_11.title, "A new book"));
+		assertTrue(m.contains(r, DC_11.creator, "A.N.Other"));
+		assertEquals(3, triples.size());
+		assertEquals(2, m.getNsPrefixMap().size());
+		assertEquals(NS_prefix, m.getNsPrefixMap().get("ns"));
+		assertEquals(DC_11.NS, m.getNsPrefixMap().get("dc"));
+
+	}
+
+	/**
+	 * Example 2: Adding some triples to a graph
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_2
+	 */
+	@Test
+	public void example2() {
+		Resource r = ResourceFactory.createResource("http://example/book1");
+		Property price = ResourceFactory.createProperty(NS_prefix + "price");
+		Literal priceV = ResourceFactory.createTypedLiteral(42);
+
+		m.setNsPrefix("dc", DC_11.NS);
+		m.add(r, DC_11.title, "Fundamentals of Compiler Design");
+
+		UpdateBuilder builder = new UpdateBuilder().addPrefix("ns", NS_prefix).addInsert(r, "ns:price",
+				priceV.asNode());
+
+		UpdateAction.execute(builder.buildRequest(), m);
+
+		assertTrue(m.contains(r, price, priceV));
+		assertTrue(m.contains(r, DC_11.title, "Fundamentals of Compiler Design"));
+		assertEquals(2, triples.size());
+		// assertEquals( 2, m.getNsPrefixMap().size());
+		// assertEquals( NS_prefix, m.getNsPrefixMap().get("ns"));
+		assertEquals(DC_11.NS, m.getNsPrefixMap().get("dc"));
+	}
+
+	/**
+	 * Example 3: Removing triples from a graph
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_3
+	 */
+	@Test
+	public void example3() {
+		Resource r = ResourceFactory.createResource("http://example/book2");
+		Property price = ResourceFactory.createProperty(NS_prefix + "price");
+		Literal priceV = ResourceFactory.createTypedLiteral(42);
+
+		m.setNsPrefix("dc", DC_11.NS);
+		m.setNsPrefix("ns", NS_prefix);
+		m.add(r, price, priceV);
+		m.add(r, DC_11.title, "David Copperfield");
+		m.add(r, DC_11.creator, "Edmund Wells");
+
+		UpdateBuilder builder = new UpdateBuilder().addPrefix("dc", DC_11.NS).addDelete(r, DC_11.title, "David Copperfield")
+				.addDelete(r, DC_11.creator, "Edmund Wells");
+
+		UpdateAction.execute(builder.buildRequest(), m);
+
+		assertTrue(m.contains(r, price, priceV));
+		assertEquals(1, triples.size());
+		assertEquals(2, m.getNsPrefixMap().size());
+		assertEquals(NS_prefix, m.getNsPrefixMap().get("ns"));
+		assertEquals(DC_11.NS, m.getNsPrefixMap().get("dc"));
+	}
+
+	/**
+	 * Example 4:
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_4
+	 */
+	@Test
+	public void example4() {
+		Resource r = ResourceFactory.createResource("http://example/book1");
+		Node graphName = NodeFactory.createURI("http://example/bookStore");
+		Dataset ds = DatasetFactory.create();
+		ds.addNamedModel(graphName.getURI(), m);
+		m.setNsPrefix("dc", DC_11.NS);
+		m.add(r, DC_11.title, "Fundamentals of Compiler Desing");
+
+		SelectBuilder sb = new SelectBuilder().addWhere(r, DC_11.title, "Fundamentals of Compiler Desing");
+		sb = new SelectBuilder().addPrefix("dc", DC_11.NS).addGraph(graphName, sb);
+
+		UpdateBuilder builder = new UpdateBuilder().addPrefix("dc", DC_11.NS).addDelete(sb);
+		UpdateRequest req = builder.buildRequest();
+
+		sb = new SelectBuilder().addWhere(r, DC_11.title, "Fundamentals of Compiler Design");
+		sb = new SelectBuilder().addPrefix("dc", DC_11.NS).addGraph(graphName, sb);
+
+		builder = new UpdateBuilder().addPrefix("dc", DC_11.NS).addInsert(sb);
+
+		builder.appendTo(req);
+
+		UpdateAction.execute(req, ds);
+
+		Model m2 = ds.getNamedModel(graphName.getURI());
+
+		assertTrue(m2.contains(r, DC_11.title, "Fundamentals of Compiler Design"));
+
+		assertEquals(1, m2.listStatements().toSet().size());
+		// assertEquals( 1, m2.getNsPrefixMap().size());
+		// assertEquals( DC.NS, m2.getNsPrefixMap().get("dc"));
+	}
+
+	/**
+	 * Example 5:
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_5
+	 */
+	@Test
+	public void example5() {
+		Resource p25 = ResourceFactory.createResource("http://example/president25");
+		Resource p27 = ResourceFactory.createResource("http://example/president27");
+		Resource p42 = ResourceFactory.createResource("http://example/president42");
+		m.setNsPrefix("foaf", FOAF.NS);
+		m.add(p25, FOAF.givenname, "Bill");
+		m.add(p25, FOAF.family_name, "McKinley");
+		m.add(p27, FOAF.givenname, "Bill");
+		m.add(p27, FOAF.family_name, "Taft");
+		m.add(p42, FOAF.givenname, "Bill");
+		m.add(p42, FOAF.family_name, "Clinton");
+
+		Node graphName = NodeFactory.createURI("http://example/addresses");
+		Dataset ds = DatasetFactory.create();
+		ds.addNamedModel(graphName.getURI(), m);
+
+		UpdateBuilder builder = new UpdateBuilder().addPrefix("foaf", FOAF.NS).with(graphName)
+				.addDelete("?person", FOAF.givenname, "Bill").addInsert("?person", FOAF.givenname, "William")
+				.addWhere("?person", FOAF.givenname, "Bill");
+
+		UpdateRequest req = builder.buildRequest();
+
+		UpdateAction.execute(req, ds);
+
+		Model m2 = ds.getNamedModel(graphName.getURI());
+		m2.write(System.out, "TURTLE");
+		List<RDFNode> nodes = m2.listObjectsOfProperty(FOAF.givenname).toList();
+		assertEquals(1, nodes.size());
+		assertEquals("William", nodes.get(0).asLiteral().toString());
+		List<Resource> subjects = m2.listSubjectsWithProperty(FOAF.givenname).toList();
+		assertEquals(3, subjects.size());
+	}
+
+	/**
+	 * Example 6:
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_6
+	 */
+	@Test
+	public void example6() {
+
+		Resource book1 = ResourceFactory.createResource("http://example/book1");
+		Resource book2 = ResourceFactory.createResource("http://example/book2");
+		Resource book3 = ResourceFactory.createResource("http://example/book3");
+
+		Literal d1977 = ResourceFactory.createTypedLiteral("1977-01-01T00:00:00-02:00", XSDDatatype.XSDdateTime);
+		Literal d1970 = ResourceFactory.createTypedLiteral("1970-01-01T00:00:00-02:00", XSDDatatype.XSDdateTime);
+		Literal d1948 = ResourceFactory.createTypedLiteral("1948-01-01T00:00:00-02:00", XSDDatatype.XSDdateTime);
+
+		Property price = ResourceFactory.createProperty(NS_prefix + "price");
+		Literal priceV = ResourceFactory.createPlainLiteral("42");
+
+		m.setNsPrefix("dc", DC_11.NS);
+		m.setNsPrefix("ns", NS_prefix);
+
+		m.add(book1, DC_11.title, "Principles of Compiler Design");
+		m.add(book1, DC_11.date, d1977);
+
+		m.add(book2, price, priceV);
+		m.add(book2, DC_11.title, "David Copperfield");
+		m.add(book2, DC_11.creator, "Edmund Wells");
+		m.add(book2, DC_11.date, d1948);
+
+		m.add(book3, DC_11.title, "SPARQL 1.1 Tutorial");
+
+		UpdateBuilder builder = new UpdateBuilder().addPrefix("dc", DC_11.NS)
+				.addPrefix("xsd", "http://www.w3.org/2001/XMLSchema#").addDelete("?book", "?p", "?v")
+				.addWhere("?book", "dc:date", "?date");
+
+		ExprFactory exprFact = builder.getExprFactory();
+		builder.addFilter(exprFact.gt(exprFact.asExpr("?date"), d1970)).addWhere("?book", "?p", "?v");
+
+		UpdateRequest req = builder.buildRequest();
+
+		UpdateAction.execute(req, m);
+
+		assertTrue(m.contains(book2, price, priceV));
+		assertTrue(m.contains(book2, DC_11.title, "David Copperfield"));
+		assertTrue(m.contains(book2, DC_11.creator, "Edmund Wells"));
+		assertTrue(m.contains(book2, DC_11.date, d1948));
+
+		assertTrue(m.contains(book3, DC_11.title, "SPARQL 1.1 Tutorial"));
+
+		assertEquals(5, triples.size());
+	}
+
+	/**
+	 * Example 7:
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_7
+	 */
+	@Test
+	public void example7() {
+		Resource will = ResourceFactory.createResource("http://example/william");
+		Resource willMail = ResourceFactory.createResource("mailto:bill@example");
+		Resource fred = ResourceFactory.createResource("http://example/fred");
+		Resource fredMail = ResourceFactory.createResource("mailto:fred@example");
+
+		Node graphName = NodeFactory.createURI("http://example/addresses");
+
+		m.add(will, RDF.type, FOAF.Person);
+		m.add(will, FOAF.givenname, "William");
+		m.add(will, FOAF.mbox, willMail);
+
+		m.add(fred, RDF.type, FOAF.Person);
+		m.add(fred, FOAF.givenname, "Fred");
+		m.add(fred, FOAF.mbox, fredMail);
+
+		Dataset ds = DatasetFactory.create();
+		ds.addNamedModel(graphName.getURI(), m);
+
+		UpdateBuilder builder = new UpdateBuilder().addPrefix("foaf", FOAF.NS).with(graphName)
+				.addDelete("?person", "?property", "?value").addWhere("?person", "?property", "?value")
+				.addWhere("?person", FOAF.givenname, "'Fred'");
+
+		UpdateAction.execute(builder.build(), ds);
+
+		Model m2 = ds.getNamedModel(graphName.getURI());
+
+		assertTrue(m2.contains(will, RDF.type, FOAF.Person));
+		assertTrue(m2.contains(will, FOAF.givenname, "William"));
+		assertTrue(m2.contains(will, FOAF.mbox, willMail));
+		assertEquals(3, m2.listStatements().toList().size());
+	}
+
+	/**
+	 * Example 8:
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_8
+	 */
+	@Test
+	public void example8() {
+
+		Resource book1 = ResourceFactory.createResource("http://example/book1");
+		Resource book2 = ResourceFactory.createResource("http://example/book2");
+		Resource book3 = ResourceFactory.createResource("http://example/book3");
+		Resource book4 = ResourceFactory.createResource("http://example/book4");
+
+		Literal d1977 = ResourceFactory.createTypedLiteral("1977-01-01T00:00:00-02:00", XSDDatatype.XSDdateTime);
+		Literal d1970 = ResourceFactory.createTypedLiteral("1970-01-01T00:00:00-02:00", XSDDatatype.XSDdateTime);
+		Literal d1948 = ResourceFactory.createTypedLiteral("1948-01-01T00:00:00-02:00", XSDDatatype.XSDdateTime);
+
+		Property price = ResourceFactory.createProperty(NS_prefix + "price");
+		Literal priceV = ResourceFactory.createPlainLiteral("42");
+
+		Node graphName1 = NodeFactory.createURI("http://example/bookStore");
+		Node graphName2 = NodeFactory.createURI("http://example/bookStore2");
+
+		Model m1 = ModelFactory.createDefaultModel();
+		m1.add(book1, DC_11.title, "Fundamentals of Compiler Design");
+		m1.add(book1, DC_11.date, d1977);
+
+		m1.add(book2, price, priceV);
+		m1.add(book2, DC_11.title, "David Copperfield");
+		m1.add(book2, DC_11.creator, "Edmund Wells");
+		m1.add(book2, DC_11.date, d1948);
+
+		m1.add(book3, DC_11.title, "SPARQL 1.1 Tutorial");
+
+		Model m2 = ModelFactory.createDefaultModel();
+		m2.add(book4, DC_11.title, "SPARQL 1.1 Tutorial");
+
+		Dataset ds = DatasetFactory.create();
+		ds.addNamedModel(graphName1.getURI(), m1);
+		ds.addNamedModel(graphName2.getURI(), m2);
+
+		ExprFactory factory = new ExprFactory();
+
+		SelectBuilder ins = new SelectBuilder().addGraph(graphName2, new SelectBuilder().addWhere("?book", "?p", "?v"));
+
+		SelectBuilder whr = new SelectBuilder().addGraph(graphName1,
+				new SelectBuilder().addWhere("?book", DC_11.date, "?date").addFilter(factory.gt("?date", d1970))
+						.addWhere("?book", "?p", "?v"));
+		UpdateBuilder builder = new UpdateBuilder().addPrefix("dc", DC_11.NS).addPrefix("xsd", XSD.NS).addInsert(ins)
+				.addWhere(whr);
+
+		UpdateAction.execute(builder.build(), ds);
+
+		m1 = ds.getNamedModel(graphName1.getURI());
+		assertEquals(7, m1.listStatements().toList().size());
+
+		assertEquals(2, m1.listStatements(book1, null, (RDFNode) null).toList().size());
+		assertTrue(m1.contains(book1, DC_11.title, "Fundamentals of Compiler Design"));
+		assertTrue(m1.contains(book1, DC_11.date, d1977));
+
+		assertEquals(4, m1.listStatements(book2, null, (RDFNode) null).toList().size());
+		assertTrue(m1.contains(book2, price, priceV));
+		assertTrue(m1.contains(book2, DC_11.title, "David Copperfield"));
+		assertTrue(m1.contains(book2, DC_11.creator, "Edmund Wells"));
+		assertTrue(m1.contains(book2, DC_11.date, d1948));
+
+		assertEquals(1, m1.listStatements(book3, null, (RDFNode) null).toList().size());
+		assertTrue(m1.contains(book3, DC_11.title, "SPARQL 1.1 Tutorial"));
+
+		m2 = ds.getNamedModel(graphName2.getURI());
+		assertEquals(3, m2.listStatements().toList().size());
+
+		assertEquals(2, m2.listStatements(book1, null, (RDFNode) null).toList().size());
+		assertTrue(m2.contains(book1, DC_11.title, "Fundamentals of Compiler Design"));
+		assertTrue(m2.contains(book1, DC_11.date, d1977));
+
+		assertEquals(1, m2.listStatements(book4, null, (RDFNode) null).toList().size());
+		assertTrue(m2.contains(book4, DC_11.title, "SPARQL 1.1 Tutorial"));
+
+	}
+
+	/**
+	 * Example 9:
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_9
+	 */
+	@Test
+	public void example9() {
+		Node graphName1 = NodeFactory.createURI("http://example/addresses");
+		Node graphName2 = NodeFactory.createURI("http://example/people");
+
+		Resource alice = ResourceFactory.createResource();
+		Resource aliceMail = ResourceFactory.createResource("mailto:alice@example.com");
+
+		Resource bob = ResourceFactory.createResource();
+
+		Model m1 = ModelFactory.createDefaultModel();
+		m1.add(alice, RDF.type, FOAF.Person);
+		m1.add(alice, FOAF.name, "Alice");
+		m1.add(alice, FOAF.mbox, aliceMail);
+
+		m1.add(bob, RDF.type, FOAF.Person);
+		m1.add(bob, FOAF.name, "Bob");
+
+		Model m2 = ModelFactory.createDefaultModel();
+
+		Dataset ds = DatasetFactory.create();
+		ds.addNamedModel(graphName1.getURI(), m1);
+		ds.addNamedModel(graphName2.getURI(), m2);
+
+		SelectBuilder ins = new SelectBuilder().addGraph(graphName2,
+				new SelectBuilder().addWhere("?person", FOAF.name, "?name").addWhere("?person", FOAF.mbox, "?email"));
+
+		SelectBuilder whr = new SelectBuilder().addGraph(graphName1, new SelectBuilder()
+				.addWhere("?person", FOAF.name, "?name").addOptional("?person", FOAF.mbox, "?email"));
+		UpdateBuilder builder = new UpdateBuilder().addInsert(ins).addWhere(whr);
+
+		UpdateAction.execute(builder.build(), ds);
+
+		m1 = ds.getNamedModel(graphName1.getURI());
+		assertEquals(5, m1.listStatements().toList().size());
+
+		assertEquals(3, m1.listStatements(alice, null, (RDFNode) null).toList().size());
+		assertTrue(m1.contains(alice, RDF.type, FOAF.Person));
+		assertTrue(m1.contains(alice, FOAF.name, "Alice"));
+		assertTrue(m1.contains(alice, FOAF.mbox, aliceMail));
+
+		assertEquals(2, m1.listStatements(bob, null, (RDFNode) null).toList().size());
+		assertTrue(m1.contains(bob, RDF.type, FOAF.Person));
+		assertTrue(m1.contains(bob, FOAF.name, "Bob"));
+
+		m2 = ds.getNamedModel(graphName2.getURI());
+		assertEquals(3, m2.listStatements().toList().size());
+
+		assertEquals(2, m2.listStatements(alice, null, (RDFNode) null).toList().size());
+		assertTrue(m2.contains(alice, FOAF.name, "Alice"));
+		assertTrue(m2.contains(alice, FOAF.mbox, aliceMail));
+
+		assertEquals(1, m2.listStatements(bob, null, (RDFNode) null).toList().size());
+		assertTrue(m2.contains(bob, FOAF.name, "Bob"));
+
+	}
+
+	/**
+	 * Example 10:
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_10
+	 */
+	@Test
+	public void example10() {
+
+		Resource book1 = ResourceFactory.createResource("http://example/book1");
+		Resource book3 = ResourceFactory.createResource("http://example/book3");
+		Resource book4 = ResourceFactory.createResource("http://example/book4");
+
+		Literal d1996 = ResourceFactory.createTypedLiteral("1996-01-01T00:00:00-02:00", XSDDatatype.XSDdateTime);
+		Literal d2000 = ResourceFactory.createTypedLiteral("2000-01-01T00:00:00-02:00", XSDDatatype.XSDdateTime);
+
+		Node graphName1 = NodeFactory.createURI("http://example/bookStore");
+		Node graphName2 = NodeFactory.createURI("http://example/bookStore2");
+
+		Model m1 = ModelFactory.createDefaultModel();
+		m1.add(book1, DC_11.title, "Fundamentals of Compiler Design");
+		m1.add(book1, DC_11.date, d1996);
+		m1.add(book1, RDF.type, DCTypes.PhysicalObject);
+
+		m1.add(book3, DC_11.title, "SPARQL 1.1 Tutorial");
+
+		Model m2 = ModelFactory.createDefaultModel();
+		m2.add(book4, DC_11.title, "SPARQL 1.1 Tutorial");
+
+		Dataset ds = DatasetFactory.create();
+		ds.addNamedModel(graphName1.getURI(), m1);
+		ds.addNamedModel(graphName2.getURI(), m2);
+
+		ExprFactory factory = new ExprFactory();
+
+		SelectBuilder ins = new SelectBuilder().addGraph(graphName2, new SelectBuilder().addWhere("?book", "?p", "?v"));
+
+		SelectBuilder whr = new SelectBuilder().addGraph(graphName1,
+				new SelectBuilder().addWhere("?book", DC_11.date, "?date").addFilter(factory.lt("?date", d2000))
+						.addWhere("?book", "?p", "?v"));
+
+		UpdateBuilder builder = new UpdateBuilder().addPrefix("dc", DC_11.NS).addPrefix("xsd", XSD.NS).addInsert(ins)
+				.addWhere(whr);
+
+		UpdateRequest req = builder.buildRequest();
+
+		builder = new UpdateBuilder().with(graphName1).addDelete("?book", "?p", "?v")
+				.addWhere("?book", DC_11.date, "?date").addWhere("?book", RDF.type, DCTypes.PhysicalObject)
+				.addFilter(factory.lt("?date", d2000)).addWhere("?book", "?p", "?v");
+
+		builder.appendTo(req);
+
+		System.out.println(req);
+
+		UpdateAction.execute(req, ds);
+
+		m1 = ds.getNamedModel(graphName1.getURI());
+		assertEquals(1, m1.listStatements().toList().size());
+
+		assertTrue(m1.contains(book3, DC_11.title, "SPARQL 1.1 Tutorial"));
+
+		m2 = ds.getNamedModel(graphName2.getURI());
+		assertEquals(4, m2.listStatements().toList().size());
+
+		assertEquals(3, m2.listStatements(book1, null, (RDFNode) null).toList().size());
+		assertTrue(m2.contains(book1, DC_11.title, "Fundamentals of Compiler Design"));
+		assertTrue(m2.contains(book1, DC_11.date, d1996));
+		assertTrue(m2.contains(book1, RDF.type, DCTypes.PhysicalObject));
+
+		assertEquals(1, m2.listStatements(book4, null, (RDFNode) null).toList().size());
+		assertTrue(m2.contains(book4, DC_11.title, "SPARQL 1.1 Tutorial"));
+
+	}
+
+	/**
+	 * Example 11:
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_11
+	 */
+	@Test
+	public void example11() {
+
+		Resource will = ResourceFactory.createResource("http://example/william");
+		Resource willMail = ResourceFactory.createResource("mailto:bill@example");
+		Resource fred = ResourceFactory.createResource("http://example/fred");
+		Resource fredMail = ResourceFactory.createResource("mailto:fred@example");
+
+		m.add(will, RDF.type, FOAF.Person);
+		m.add(will, FOAF.givenname, "William");
+		m.add(will, FOAF.mbox, willMail);
+
+		m.add(fred, RDF.type, FOAF.Person);
+		m.add(fred, FOAF.givenname, "Fred");
+		m.add(fred, FOAF.mbox, fredMail);
+
+		UpdateBuilder builder = new UpdateBuilder().addWhere("?person", FOAF.givenname, "Fred").addWhere("?person",
+				"?property", "?value");
+
+		UpdateAction.execute(builder.buildDeleteWhere(), m);
+
+		assertEquals(3, m.listStatements().toList().size());
+		assertTrue(m.contains(will, RDF.type, FOAF.Person));
+		assertTrue(m.contains(will, FOAF.givenname, "William"));
+		assertTrue(m.contains(will, FOAF.mbox, willMail));
+	}
+
+	/**
+	 * Example 12:
+	 * 
+	 * @see https://www.w3.org/TR/sparql11-update/#example_12
+	 */
+	@Test
+	public void example12() {
+
+		Resource will = ResourceFactory.createResource("http://example/william");
+		Resource willMail = ResourceFactory.createResource("mailto:bill@example");
+		Resource fred = ResourceFactory.createResource("http://example/fred");
+		Resource fredMail = ResourceFactory.createResource("mailto:fred@example");
+
+		Node graphName1 = NodeFactory.createURI("http://example/names");
+		Node graphName2 = NodeFactory.createURI("http://example/addresses");
+
+		Model m1 = ModelFactory.createDefaultModel();
+		m1.add(will, RDF.type, FOAF.Person);
+		m1.add(will, FOAF.givenname, "William");
+		m1.add(fred, RDF.type, FOAF.Person);
+		m1.add(fred, FOAF.givenname, "Fred");
+
+		Model m2 = ModelFactory.createDefaultModel();
+		m2.add(will, FOAF.mbox, willMail);
+		m2.add(fred, FOAF.mbox, fredMail);
+
+		Dataset ds = DatasetFactory.create();
+		ds.addNamedModel(graphName1.getURI(), m1);
+		ds.addNamedModel(graphName2.getURI(), m2);
+
+		UpdateBuilder builder = new UpdateBuilder()
+				.addGraph(graphName1,
+						new SelectBuilder().addWhere("?person", FOAF.givenname, "Fred").addWhere("?person", "?property",
+								"?value1"))
+				.addGraph(graphName2, new SelectBuilder().addWhere("?person", "?property2", "?value2"));
+
+		UpdateAction.execute(builder.buildDeleteWhere(), ds);
+
+		m1 = ds.getNamedModel(graphName1.getURI());
+		assertEquals(2, m1.listStatements().toList().size());
+		assertTrue(m1.contains(will, RDF.type, FOAF.Person));
+		assertTrue(m1.contains(will, FOAF.givenname, "William"));
+
+		m2 = ds.getNamedModel(graphName2.getURI());
+		assertEquals(1, m2.listStatements().toList().size());
+		assertTrue(m2.contains(will, FOAF.mbox, willMail));
+	}
+
+	// /**
+	// * Example 13:
+	// *
+	// * @see https://www.w3.org/TR/sparql11-update/#example_13
+	// */
+	// @Test
+	// public void example13()
+	// {
+	// System.out.println( "COPY Not implemented");
+	// }
+	// /**
+	// * Example 14:
+	// *
+	// * @see https://www.w3.org/TR/sparql11-update/#example_14
+	// */
+	// @Test
+	// public void example14()
+	// {
+	// System.out.println( "MOVE Not implemented");
+	// }
+	//
+	// /**
+	// * Example 15:
+	// *
+	// * @see https://www.w3.org/TR/sparql11-update/#example_15
+	// */
+	// @Test
+	// public void example15()
+	// {
+	// System.out.println( "ADD Not implemented");
+	// }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..e359cea
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java
@@ -0,0 +1,411 @@
+/*
+ * 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;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jena.arq.querybuilder.UpdateBuilder;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.graph.impl.CollectionGraph;
+import org.apache.jena.rdf.model.Literal;
+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.Resource;
+import org.apache.jena.rdf.model.ResourceFactory;
+import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.modify.request.UpdateDataDelete;
+import org.apache.jena.sparql.modify.request.UpdateDataInsert;
+import org.apache.jena.sparql.modify.request.UpdateModify;
+import org.apache.jena.sparql.syntax.Element;
+import org.apache.jena.sparql.syntax.ElementGroup;
+import org.apache.jena.sparql.syntax.ElementPathBlock;
+import org.apache.jena.update.Update;
+import org.apache.jena.update.UpdateAction;
+import org.apache.jena.vocabulary.DC_11;
+import org.junit.Test;
+
+public class UpdateBuilderTest {
+	
+	private Node g = NodeFactory.createURI("http://example.com/graph");
+	private Node s = NodeFactory.createURI("http://example.com/subject");
+	private Node p = NodeFactory.createURI("http://example.com/predicate");
+	private Node o = NodeFactory.createURI("http://example.com/object");
+
+	@Test
+	public  void testInsert_SPO()
+	{
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addInsert( s, p, o);
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataInsert);
+		UpdateDataInsert udi = (UpdateDataInsert)update;
+		List<Quad> quads = udi.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( Quad.defaultGraphNodeGenerated, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+
+	@Test
+	public  void testInsert_Triple()
+	{
+		Triple t = new Triple( s, p ,o );
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addInsert( t );
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataInsert);
+		UpdateDataInsert udi = (UpdateDataInsert)update;
+		List<Quad> quads = udi.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( Quad.defaultGraphNodeGenerated, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+
+	@Test
+	public  void testInsert_NodeTriple()
+	{
+		Triple t = new Triple( s, p ,o );
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addInsert( g, t );
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataInsert);
+		UpdateDataInsert udi = (UpdateDataInsert)update;
+		List<Quad> quads = udi.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( g, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+	
+	@Test
+	public  void testInsert_GSPO()
+	{
+		
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addInsert( g, s, p, o);
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataInsert);
+		UpdateDataInsert udi = (UpdateDataInsert)update;
+		List<Quad> quads = udi.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( g, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+	
+	@Test
+	public  void testInsert_Quad()
+	{
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addInsert( new Quad( g, s, p, o) );
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataInsert);
+		UpdateDataInsert udi = (UpdateDataInsert)update;
+		List<Quad> quads = udi.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( g, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+
+	@Test
+	public void testInsertValueReplacement()
+	{
+		Var v = Var.alloc("v");
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addInsert( v, p, o);
+		builder.setVar( v, s );
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataInsert);
+		UpdateDataInsert udi = (UpdateDataInsert)update;
+		List<Quad> quads = udi.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( Quad.defaultGraphNodeGenerated, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+	
+	@Test
+	public  void testDelete_SPO()
+	{
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addDelete( s, p, o);
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataDelete);
+		UpdateDataDelete udd = (UpdateDataDelete)update;
+		List<Quad> quads = udd.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( Quad.defaultGraphNodeGenerated, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+
+	@Test
+	public  void testDelete_Triple()
+	{
+		Triple t = new Triple( s, p ,o );
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addDelete( t );
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataDelete);
+		UpdateDataDelete udd = (UpdateDataDelete)update;
+		List<Quad> quads = udd.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( Quad.defaultGraphNodeGenerated, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+
+	@Test
+	public  void testDelete_NodeTriple()
+	{
+		Triple t = new Triple( s, p ,o );
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addDelete( g, t );
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataDelete);
+		UpdateDataDelete udd = (UpdateDataDelete)update;
+		List<Quad> quads = udd.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( g, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+	
+	@Test
+	public  void testDelete_GSPO()
+	{
+		
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addDelete( g, s, p, o);
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataDelete);
+		UpdateDataDelete udd = (UpdateDataDelete)update;
+		List<Quad> quads = udd.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( g, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+	
+	@Test
+	public  void testDelete_Quad()
+	{
+		
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addDelete( new Quad( g, s, p, o) );
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataDelete);
+		UpdateDataDelete udd = (UpdateDataDelete)update;
+		List<Quad> quads = udd.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( g, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+
+	@Test
+	public void testDeleteValueReplacement()
+	{
+		Var v = Var.alloc("v");
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addDelete( v, p, o);
+		builder.setVar( v, s );
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateDataDelete);
+		UpdateDataDelete udd = (UpdateDataDelete)update;
+		List<Quad> quads = udd.getQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( Quad.defaultGraphNodeGenerated, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+	}
+	
+	@Test
+	public  void testInsertAndDelete()
+	{
+		UpdateBuilder builder = new UpdateBuilder();
+		builder.addInsert( new Quad( g, s, p, o) );
+		builder.addDelete( new Triple( s, p, o) );
+		builder.addWhere( null, p, "foo");
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateModify);
+		UpdateModify um = (UpdateModify)update;
+		List<Quad> quads = um.getInsertQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( g, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+		
+		quads = um.getDeleteQuads();
+		assertEquals( 1, quads.size());
+		q = quads.get(0);
+		assertEquals( Quad.defaultGraphNodeGenerated, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+		
+		Element e = um.getWherePattern();
+		assertTrue( e instanceof ElementGroup );
+		ElementGroup eg = (ElementGroup) e;
+		assertEquals( 1, eg.getElements().size());
+		ElementPathBlock epb = (ElementPathBlock)eg.getElements().get(0);
+		Triple t = epb.getPattern().get(0).asTriple();
+		assertEquals( Node.ANY, t.getSubject());
+		assertEquals( p, t.getPredicate());
+		assertEquals( builder.makeNode("foo"), t.getObject());
+	}
+	
+	@Test
+	public  void testInsertAndDeleteWithVar()
+	{
+		UpdateBuilder builder = new UpdateBuilder();
+		Var v = Var.alloc("v");
+
+		builder.addInsert( new Quad( g, s, v, o) );
+		builder.addDelete( new Triple( s, v, o) );
+		builder.addWhere( null, v, "foo");
+		builder.setVar( v, p );
+		Update update = builder.build();
+		assertTrue( update instanceof UpdateModify);
+		UpdateModify um = (UpdateModify)update;
+		List<Quad> quads = um.getInsertQuads();
+		assertEquals( 1, quads.size());
+		Quad q = quads.get(0);
+		assertEquals( g, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+		
+		quads = um.getDeleteQuads();
+		assertEquals( 1, quads.size());
+		q = quads.get(0);
+		assertEquals( Quad.defaultGraphNodeGenerated, q.getGraph());
+		assertEquals( s, q.getSubject());
+		assertEquals( p, q.getPredicate());
+		assertEquals( o, q.getObject());
+		
+		Element e = um.getWherePattern();
+		assertTrue( e instanceof ElementGroup );
+		ElementGroup eg = (ElementGroup) e;
+		assertEquals( 1, eg.getElements().size());
+		ElementPathBlock epb = (ElementPathBlock)eg.getElements().get(0);
+		Triple t = epb.getPattern().get(0).asTriple();
+		assertEquals( Node.ANY, t.getSubject());
+		assertEquals( p, t.getPredicate());
+		assertEquals( builder.makeNode("foo"), t.getObject());
+	}
+	
+	// testsbased on the examples
+
+	/*
+	 * 	Example 1: Adding some triples to a graph
+
+	This snippet describes two RDF triples to be inserted into the default graph of the Graph Store.
+
+	PREFIX dc: <http://purl.org/dc/elements/1.1/>
+	INSERT DATA
+	{ 
+	  <http://example/book1> dc:title "A new book" ;
+	                         dc:creator "A.N.Other" .
+	}
+
+	Data before:
+
+	# Default graph
+	@prefix dc: <http://purl.org/dc/elements/1.1/> .
+	@prefix ns: <http://example.org/ns#> .
+
+	<http://example/book1> ns:price 42 .
+
+	Data after:
+
+	# Default graph
+	@prefix dc: <http://purl.org/dc/elements/1.1/> .
+	@prefix ns: <http://example.org/ns#> .
+
+	<http://example/book1> ns:price 42 .
+	<http://example/book1> dc:title "A new book" .
+	<http://example/book1> dc:creator "A.N.Other" .
+
+	 */
+	@Test
+	public void example1() {
+		Node n = NodeFactory.createURI("http://example/book1");
+		Node priceN = NodeFactory.createURI("http://example.org/ns#price");
+		Node priceV = NodeFactory.createLiteral("42");
+		UpdateBuilder builder = new UpdateBuilder()
+		.addPrefix( "dc", DC_11.NS)
+		.addInsert( n, DC_11.title, "A new book")
+		.addInsert( n, DC_11.creator, "A.N.Other");
+		
+		List<Triple> triples = new ArrayList<Triple>();
+		triples.add( new Triple( n, priceN, priceV ));
+		Graph g = new CollectionGraph( triples );
+		Model m = ModelFactory.createModelForGraph(g);
+		m.setNsPrefix( "dc", DC_11.NS);
+		m.setNsPrefix("ns", "http://example.org/ns#");
+	
+		UpdateAction.execute( builder.build(), m);
+		
+		Resource r = ResourceFactory.createResource( n.getURI() );
+		Property rPriceP = ResourceFactory.createProperty( priceN.getURI() );
+		Literal rPriceV = ResourceFactory.createPlainLiteral("42");
+		assertTrue( m.contains( r, rPriceP, rPriceV));
+		assertTrue( m.contains( r, DC_11.title, "A new book"));
+		assertTrue( m.contains( r, DC_11.creator, "A.N.Other"));
+		assertEquals( 3, triples.size());
+		
+	}
+	
+}


[3/6] jena git commit: removed unused imports

Posted by cl...@apache.org.
removed unused imports

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

Branch: refs/heads/master
Commit: c099281557b677d094e84df3e33e975163b39e5d
Parents: 7d96286
Author: Claude Warren <cl...@apache.org>
Authored: Sun Jun 4 12:12:26 2017 +0100
Committer: Claude Warren <cl...@apache.org>
Committed: Sun Jun 4 12:12:26 2017 +0100

----------------------------------------------------------------------
 .../java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java   | 2 --
 1 file changed, 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/c0992815/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/SelectBuilderTest.java
----------------------------------------------------------------------
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 ebe238e..ce3284e 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
@@ -23,7 +23,6 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import org.apache.jena.arq.AbstractRegexpBasedTest;
-import org.apache.jena.arq.querybuilder.clauses.SelectClause;
 import org.apache.jena.query.Query;
 import org.apache.jena.query.QueryExecution;
 import org.apache.jena.query.QueryExecutionFactory;
@@ -38,7 +37,6 @@ import org.apache.jena.vocabulary.RDF;
 import org.apache.jena.vocabulary.XSD;
 import org.junit.Before;
 import org.junit.Test;
-import org.xenei.junit.contract.ContractTest;
 
 public class SelectBuilderTest extends AbstractRegexpBasedTest {
 


[6/6] jena git commit: removed deadcode and System.out statements

Posted by cl...@apache.org.
removed deadcode and System.out statements

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

Branch: refs/heads/master
Commit: bd357d406045bd82f5ce899d2ebbc3e6fdf33dca
Parents: 7043d34
Author: Claude Warren <cl...@apache.org>
Authored: Sun Jun 4 12:30:04 2017 +0100
Committer: Claude Warren <cl...@apache.org>
Committed: Sun Jun 4 12:30:04 2017 +0100

----------------------------------------------------------------------
 .../querybuilder/UpdateBuilderExampleTests.java | 36 +-------------------
 1 file changed, 1 insertion(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/bd357d40/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderExampleTests.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderExampleTests.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderExampleTests.java
index 894a98f..45db245 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderExampleTests.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderExampleTests.java
@@ -229,7 +229,6 @@ public class UpdateBuilderExampleTests {
 		UpdateAction.execute(req, ds);
 
 		Model m2 = ds.getNamedModel(graphName.getURI());
-		m2.write(System.out, "TURTLE");
 		List<RDFNode> nodes = m2.listObjectsOfProperty(FOAF.givenname).toList();
 		assertEquals(1, nodes.size());
 		assertEquals("William", nodes.get(0).asLiteral().toString());
@@ -523,8 +522,6 @@ public class UpdateBuilderExampleTests {
 
 		builder.appendTo(req);
 
-		System.out.println(req);
-
 		UpdateAction.execute(req, ds);
 
 		m1 = ds.getNamedModel(graphName1.getURI());
@@ -624,36 +621,5 @@ public class UpdateBuilderExampleTests {
 		assertEquals(1, m2.listStatements().toList().size());
 		assertTrue(m2.contains(will, FOAF.mbox, willMail));
 	}
-
-	// /**
-	// * Example 13:
-	// *
-	// * @see https://www.w3.org/TR/sparql11-update/#example_13
-	// */
-	// @Test
-	// public void example13()
-	// {
-	// System.out.println( "COPY Not implemented");
-	// }
-	// /**
-	// * Example 14:
-	// *
-	// * @see https://www.w3.org/TR/sparql11-update/#example_14
-	// */
-	// @Test
-	// public void example14()
-	// {
-	// System.out.println( "MOVE Not implemented");
-	// }
-	//
-	// /**
-	// * Example 15:
-	// *
-	// * @see https://www.w3.org/TR/sparql11-update/#example_15
-	// */
-	// @Test
-	// public void example15()
-	// {
-	// System.out.println( "ADD Not implemented");
-	// }
+	
 }


[2/6] jena git commit: Initial implementation with tests

Posted by cl...@apache.org.
Initial implementation with tests

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

Branch: refs/heads/master
Commit: 7d96286e1b49dc170604dd76f81abfc3f397541a
Parents: a2fb93c
Author: Claude Warren <cl...@apache.org>
Authored: Sun Jun 4 12:07:56 2017 +0100
Committer: Claude Warren <cl...@apache.org>
Committed: Sun Jun 4 12:07:56 2017 +0100

----------------------------------------------------------------------
 .../arq/querybuilder/AbstractQueryBuilder.java  |    5 +
 .../jena/arq/querybuilder/UpdateBuilder.java    | 1027 ++++++++++++++++++
 .../arq/querybuilder/handlers/WhereHandler.java |   23 +-
 .../updatebuilder/PrefixHandler.java            |  115 ++
 .../updatebuilder/QBQuadHolder.java             |   79 ++
 .../querybuilder/updatebuilder/QuadHolder.java  |   46 +
 .../updatebuilder/QuadIteratorBuilder.java      |  180 +++
 .../updatebuilder/SingleQuadHolder.java         |   97 ++
 .../updatebuilder/WhereProcessor.java           |  433 ++++++++
 .../src/test/java/Example10.java                |  104 ++
 .../querybuilder/UpdateBuilderExampleTests.java |  659 +++++++++++
 .../arq/querybuilder/UpdateBuilderTest.java     |  411 +++++++
 12 files changed, 3175 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilder.java
----------------------------------------------------------------------
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 ed18272..17be323 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
@@ -50,6 +50,7 @@ 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.ElementGroup;
+import org.apache.jena.sparql.syntax.ElementSubQuery;
 import org.apache.jena.sparql.util.ExprUtils;
 import org.apache.jena.sparql.util.NodeFactoryExtra ;
 
@@ -132,6 +133,10 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>>
 		return NodeFactory.createLiteral(LiteralLabelFactory.createTypedLiteral(o));
 	}
 		
+	public ElementSubQuery asSubQuery() {
+		return getWhereHandler().makeSubQuery( this );
+	}
+	
 	/**
 	 * Make a triple path from the objects.
 	 * 

http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/UpdateBuilder.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..93aeae6
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/UpdateBuilder.java
@@ -0,0 +1,1027 @@
+/*
+ * 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;
+
+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 org.apache.jena.arq.querybuilder.clauses.PrologClause;
+import org.apache.jena.arq.querybuilder.clauses.WhereClause;
+import org.apache.jena.arq.querybuilder.handlers.WhereHandler;
+import org.apache.jena.arq.querybuilder.updatebuilder.PrefixHandler;
+import org.apache.jena.arq.querybuilder.updatebuilder.QBQuadHolder;
+import org.apache.jena.arq.querybuilder.updatebuilder.QuadHolder;
+import org.apache.jena.arq.querybuilder.updatebuilder.SingleQuadHolder;
+import org.apache.jena.arq.querybuilder.updatebuilder.WhereProcessor;
+import org.apache.jena.graph.FrontsTriple;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.query.QueryParseException;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.shared.PrefixMapping;
+import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.sparql.core.TriplePath;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.expr.Expr;
+import org.apache.jena.sparql.lang.sparql_11.ParseException;
+import org.apache.jena.sparql.modify.request.QuadAcc;
+import org.apache.jena.sparql.modify.request.QuadDataAcc;
+import org.apache.jena.sparql.modify.request.UpdateDataDelete;
+import org.apache.jena.sparql.modify.request.UpdateDataInsert;
+import org.apache.jena.sparql.modify.request.UpdateDeleteWhere;
+import org.apache.jena.sparql.modify.request.UpdateModify;
+import org.apache.jena.update.Update;
+import org.apache.jena.update.UpdateRequest;
+import org.apache.jena.util.iterator.ExtendedIterator;
+import org.apache.jena.util.iterator.NiceIterator;
+import org.apache.jena.vocabulary.RDF;
+
+/**
+ * Class to build update requests.
+ *
+ */
+public class UpdateBuilder {
+
+	private final PrefixHandler prefixHandler;
+	private final WhereProcessor whereProcessor;
+	private List<QuadHolder> inserts = new ArrayList<QuadHolder>();
+	private List<QuadHolder> deletes = new ArrayList<QuadHolder>();
+	private Map<Var, Node> values;
+	private Node with;
+
+	/**
+	 * Constructor.
+	 */
+	public UpdateBuilder() {
+		this.prefixHandler = new PrefixHandler();
+		this.whereProcessor = new WhereProcessor(prefixHandler);
+		this.values = new HashMap<Var, Node>();
+		this.with = null;
+	}
+
+	/**
+	 * Constructor. Uses the prefixes from the prolog clause. <b>May modify the
+	 * contents of the prefix mapping in the prolog handler</b>
+	 * 
+	 * @param prologClause
+	 *            the default prefixes for this builder.
+	 */
+	public UpdateBuilder(PrologClause<?> prologClause) {
+		this(prologClause.getPrologHandler().getPrefixes());
+	}
+
+	/**
+	 * Constructor. Uses the specified prefix mapping. <b>May modify the
+	 * contents of the prefix mapping</b>
+	 * 
+	 * @param pMap
+	 *            the prefix mapping to use.
+	 */
+	public UpdateBuilder(PrefixMapping pMap) {
+		this.prefixHandler = new PrefixHandler(pMap);
+		this.whereProcessor = new WhereProcessor(prefixHandler);
+	}
+
+	// conver a collection of QuadHolder to an iterator on quads.
+	private ExtendedIterator<Quad> getQuads(Collection<QuadHolder> holders) {
+		ExtendedIterator<Quad> result = NiceIterator.emptyIterator();
+		for (QuadHolder holder : holders) {
+			result = result.andThen(holder.setValues(values).getQuads());
+		}
+		return result;
+	}
+
+	/**
+	 * Build the update.
+	 * 
+	 * <b>Note: the update does not include the prefix statements</b> use
+	 * buildRequest() or appendTo() methods to include the prefix statements.
+	 * 
+	 * @return the update.
+	 */
+	public Update build() {
+
+		if (deletes.isEmpty() && inserts.isEmpty()) {
+			throw new IllegalStateException("At least one delete or insert must be specified");
+		}
+
+		if (whereProcessor.isEmpty()) {
+			return buildNoWhere();
+		}
+		return buildWhere();
+	}
+
+	/**
+	 * Build as an UpdateRequest with prefix mapping set.
+	 * 
+	 * @return a new UpdateRequest
+	 */
+	public UpdateRequest buildRequest() {
+		UpdateRequest req = new UpdateRequest(build());
+		req.setPrefixMapping(prefixHandler.getPrefixes());
+		return req;
+	}
+
+	/**
+	 * Appends the new Update to the UpdateRequest.
+	 * 
+	 * @param req
+	 *            the UpdateRequest to append this Update to.
+	 * @return the req parameter for chaining.
+	 */
+	public UpdateRequest appendTo(UpdateRequest req) {
+		req.add(build());
+		for (Map.Entry<String, String> entry : prefixHandler.getPrefixes().getNsPrefixMap().entrySet()) {
+			req.setPrefix(entry.getKey(), entry.getValue());
+		}
+		return req;
+	}
+
+	// build updates without where clauses
+	private Update buildNoWhere() {
+		if (inserts.isEmpty()) {
+			QuadDataAcc quadData = new QuadDataAcc(getQuads(deletes).mapWith(new Function<Quad, Quad>() {
+				@Override
+				public Quad apply(Quad arg0) {
+					return check(arg0);
+				}
+			}).toList());
+			return new UpdateDataDelete(quadData);
+		}
+		if (deletes.isEmpty()) {
+			QuadDataAcc quadData = new QuadDataAcc(getQuads(inserts).mapWith(new Function<Quad, Quad>() {
+
+				@Override
+				public Quad apply(Quad t) {
+					return check(t);
+				}
+
+			}).toList());
+			return new UpdateDataInsert(quadData);
+		}
+
+		throw new IllegalStateException("Can not have both insert and delete without a where clause");
+	}
+
+	// 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)
+		{
+			Node graph = values.get(with);
+			if (graph == null) {
+				graph = with;
+			}
+			retval.setWithIRI(graph);
+		}
+		QuadAcc acc;
+		Iterator<Quad> iter;
+
+		if (!inserts.isEmpty()) {
+			retval.setHasInsertClause(true);
+			acc = retval.getInsertAcc();
+			iter = getQuads(inserts);
+			while (iter.hasNext()) {
+				acc.addQuad(iter.next());
+			}
+		}
+		if (!deletes.isEmpty()) {
+			retval.setHasDeleteClause(true);
+			acc = retval.getDeleteAcc();
+
+			iter = getQuads(deletes);
+			while (iter.hasNext()) {
+				acc.addQuad(iter.next());
+			}
+		}
+		
+		retval.setElement(whereProcessor.setVars(values));
+		
+		return retval;
+
+	}
+
+	/**
+	 * Convert the object to a node.
+	 * 
+	 * Shorthand for AbstractQueryBuilder.makeNode( o, prefixes )
+	 * 
+	 * @see AbstractQueryBuilder#makeNode(Object)
+	 * 
+	 * @param o
+	 *            the object to convert to a node.
+	 * @return the Node.
+	 */
+	public Node makeNode(Object o) {
+		return AbstractQueryBuilder.makeNode(o, prefixHandler.getPrefixes());
+	}
+
+	/**
+	 * Convert the object to a node.
+	 * 
+	 * Shorthand for AbstractQueryBuilder.makeVar( o )
+	 * 
+	 * @see AbstractQueryBuilder#makeVar(Object)
+	 * 
+	 * @param o
+	 *            the object to convert to a var.
+	 * @return the Var.
+	 */
+
+	public Var makeVar(Object o) {
+		return AbstractQueryBuilder.makeVar(o);
+	}
+
+	/**
+	 * Quote a string.
+	 * 
+	 * Shorthand for AbstractQueryBuilder.quote( s )
+	 * 
+	 * @see AbstractQueryBuilder#quote(String)
+	 * 
+	 * 
+	 * @param s
+	 *            the string to quote.
+	 * @return the quoted string.
+	 */
+	public String quote(String s) {
+		return AbstractQueryBuilder.quote(s);
+	}
+
+	/**
+	 * Add a quad to the insert statement.
+	 * 
+	 * Arguments are converted to nodes using the makeNode() method.
+	 * 
+	 * @see #makeNode(Object)
+	 * @param g
+	 *            the graph
+	 * @param s
+	 *            the subject
+	 * @param p
+	 *            the predicate
+	 * @param o
+	 *            the object
+	 * @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)));
+	}
+
+	/**
+	 * Add a quad to the insert statement.
+	 * 
+	 * 
+	 * @param quad
+	 *            the quad to add.
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addInsert(Quad quad) {
+		inserts.add(new SingleQuadHolder(quad));
+		return this;
+	}
+
+	/**
+	 * Add a triple to the insert statement.
+	 * 
+	 * Arguments are converted to nodes using the makeNode() method.
+	 * 
+	 * @see #makeNode(Object)
+	 * @param s
+	 *            the subject
+	 * @param p
+	 *            the predicate
+	 * @param o
+	 *            the object
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addInsert(Object s, Object p, Object o) {
+		addInsert(new Triple(makeNode(s), makeNode(p), makeNode(o)));
+		return this;
+	}
+
+	/**
+	 * Add a triple to the insert statement.
+	 * 
+	 * @param t
+	 *            the triple to add.
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addInsert(Triple t) {
+		inserts.add(new SingleQuadHolder( t ));
+		return this;
+	}
+
+	/**
+	 * Add a triple in a specified graph to the insert statement.
+	 * 
+	 * The graph object is converted by a call to makeNode().
+	 * 
+	 * @see #makeNode(Object)
+	 * @param g
+	 *            the graph for the triple.
+	 * @param t
+	 *            the triple to add.
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addInsert(Object g, Triple t) {
+		Quad q = new Quad(AbstractQueryBuilder.makeNode(g, prefixHandler.getPrefixes()), t);
+		inserts.add(new SingleQuadHolder(q));
+		return this;
+	}
+
+	/**
+	 * Add the statements from the where clause in the specified query builder
+	 * to the insert statement.
+	 * 
+	 * @see #makeNode(Object)
+	 * @param queryBuilder
+	 *            The query builder to extract the where clause from.
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addInsert(AbstractQueryBuilder<?> queryBuilder) {
+		inserts.add(new QBQuadHolder( queryBuilder));
+		return this;
+	}
+
+	/**
+	 * Add the statements from the where clause in the specified query builder
+	 * to the insert statements for the specified graph.
+	 * 
+	 * The graph object is converted by a call to makeNode().
+	 * 
+	 * @see #makeNode(Object)
+	 * @param graph
+	 *            the graph to add the statements to.
+	 * @param queryBuilder
+	 *            The query builder to extract the where clause from.
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addInsert(Object graph, AbstractQueryBuilder<?> queryBuilder) {
+		inserts.add(new QBQuadHolder(AbstractQueryBuilder.makeNode(graph, prefixHandler.getPrefixes()), queryBuilder));
+		return this;
+	}
+
+	/**
+	 * Add a quad to the delete statement.
+	 * 
+	 * Arguments are converted to nodes using the makeNode() method.
+	 * 
+	 * @see #makeNode(Object)
+	 * @param g
+	 *            the graph
+	 * @param s
+	 *            the subject
+	 * @param p
+	 *            the predicate
+	 * @param o
+	 *            the object
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addDelete(Object g, Object s, Object p, Object o) {
+		return addDelete(new Quad(AbstractQueryBuilder.makeNode(g, prefixHandler.getPrefixes()),
+				AbstractQueryBuilder.makeNode(s, prefixHandler.getPrefixes()),
+				AbstractQueryBuilder.makeNode(p, prefixHandler.getPrefixes()),
+				AbstractQueryBuilder.makeNode(o, prefixHandler.getPrefixes())));
+	}
+
+	/**
+	 * Add a quad to the delete statement.
+	 * 
+	 * 
+	 * @param quad
+	 *            the quad to add.
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addDelete(Quad quad) {
+		deletes.add(new SingleQuadHolder(quad));
+		return this;
+	}
+
+	/**
+	 * Add a triple to the delete statement.
+	 * 
+	 * Arguments are converted to nodes using the makeNode() method.
+	 * 
+	 * @see #makeNode(Object)
+	 * @param s
+	 *            the subject
+	 * @param p
+	 *            the predicate
+	 * @param o
+	 *            the object
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addDelete(Object s, Object p, Object o) {
+		addDelete(new Triple(AbstractQueryBuilder.makeNode(s, prefixHandler.getPrefixes()),
+				AbstractQueryBuilder.makeNode(p, prefixHandler.getPrefixes()),
+				AbstractQueryBuilder.makeNode(o, prefixHandler.getPrefixes())));
+		return this;
+	}
+
+	/**
+	 * Add a triple to the delete statement.
+	 * 
+	 * 
+	 * @param t
+	 *            the triple to add.
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addDelete(Triple t) {
+		deletes.add(new SingleQuadHolder(t));
+		return this;
+	}
+
+	/**
+	 * Add a triple in a specified graph to the delete statement.
+	 * 
+	 * The graph object is converted by a call to makeNode().
+	 * 
+	 * @see #makeNode(Object)
+	 * @param g
+	 *            the graph for the triple.
+	 * @param t
+	 *            the triple to add.
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addDelete(Object g, Triple t) {
+		Quad q = new Quad(AbstractQueryBuilder.makeNode(g, prefixHandler.getPrefixes()), t);
+		deletes.add(new SingleQuadHolder(q));
+		return this;
+	}
+
+	/**
+	 * Add the statements from the where clause in the specified query builder
+	 * to the delete statement.
+	 * 
+	 * @see #makeNode(Object)
+	 * @param queryBuilder
+	 *            The query builder to extract the where clause from.
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addDelete(AbstractQueryBuilder<?> queryBuilder) {
+		deletes.add(new QBQuadHolder( queryBuilder));
+		return this;
+	}
+
+	/**
+	 * Add the statements from the where clause in the specified query builder
+	 * to the delete statements for the specified graph.
+	 * 
+	 * The graph object is converted by a call to makeNode().
+	 * 
+	 * @see #makeNode(Object)
+	 * @param graph
+	 *            the graph to add the statements to.
+	 * @param queryBuilder
+	 *            The query builder to extract the where clause from.
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder addDelete(Object graph, AbstractQueryBuilder<?> queryBuilder) {
+		deletes.add(new QBQuadHolder(AbstractQueryBuilder.makeNode(graph, prefixHandler.getPrefixes()), queryBuilder));
+		return this;
+	}
+
+	/**
+	 * Add the prefix to the prefix mapping.
+	 * 
+	 * @param pfx
+	 *            the prefix to add.
+	 * @param uri
+	 *            the uri for the prefix.
+	 * @return this builder for chaining
+	 */
+	public UpdateBuilder addPrefix(String pfx, Resource uri) {
+		return addPrefix(pfx, uri.getURI());
+	}
+
+	/**
+	 * Add the prefix to the prefix mapping.
+	 * 
+	 * @param pfx
+	 *            the prefix to add.
+	 * @param uri
+	 *            the uri for the prefix.
+	 * @return this builder for chaining
+	 */
+	public UpdateBuilder addPrefix(String pfx, Node uri) {
+		return addPrefix(pfx, uri.getURI());
+	}
+
+	/**
+	 * Add the prefix to the prefix mapping.
+	 * 
+	 * @param pfx
+	 *            the prefix to add.
+	 * @param uri
+	 *            the uri for the prefix.
+	 * @return this builder for chaining
+	 */
+	public UpdateBuilder addPrefix(String pfx, String uri) {
+		prefixHandler.addPrefix(pfx, uri);
+		return this;
+	}
+
+	/**
+	 * Add the prefixes to the prefix mapping.
+	 * 
+	 * @param prefixes
+	 *            the prefixes to add.
+	 * @return this builder for chaining
+	 */
+
+	public UpdateBuilder addPrefixes(Map<String, String> prefixes) {
+		prefixHandler.addPrefixes(prefixes);
+		return this;
+	}
+
+	/**
+	 * Get an ExprFactory that uses the prefixes from this builder.
+	 * 
+	 * @return the EpxressionFactory.
+	 */
+	public ExprFactory getExprFactory() {
+		return prefixHandler.getExprFactory();
+	}
+
+	/**
+	 * Set a variable replacement. During build all instances of var in the
+	 * query will be replaced with value. If value is null the replacement is
+	 * cleared.
+	 * 
+	 * @param var
+	 *            The variable to replace
+	 * @param value
+	 *            The value to replace it with or null to remove the
+	 *            replacement.
+	 */
+	public void setVar(Var var, Node value) {
+		if (value == null) {
+			values.remove(var);
+		} else {
+			values.put(var, value);
+		}
+	}
+
+	/**
+	 * Set a variable replacement. During build all instances of var in the
+	 * query will be replaced with value. If value is null the replacement is
+	 * cleared.
+	 * 
+	 * See {@link #makeVar} for conversion of the var param. See
+	 * {@link #makeNode} for conversion of the value param.
+	 * 
+	 * @param var
+	 *            The variable to replace.
+	 * @param value
+	 *            The value to replace it with or null to remove the
+	 *            replacement.
+	 */
+	public void setVar(Object var, Object value) {
+		if (value == null) {
+			setVar(AbstractQueryBuilder.makeVar(var), null);
+		} else {
+			setVar(AbstractQueryBuilder.makeVar(var),
+					AbstractQueryBuilder.makeNode(value, prefixHandler.getPrefixes()));
+		}
+	}
+
+	private Quad check(Quad q) {
+		if (Var.isVar(q.getGraph()))
+			throw new QueryParseException("Variables not permitted in data quad", -1, -1);
+		if (Var.isVar(q.getSubject()) || Var.isVar(q.getPredicate()) || Var.isVar(q.getObject()))
+			throw new QueryParseException("Variables not permitted in data quad", -1, -1);
+		if (q.getSubject().isLiteral())
+			throw new QueryParseException("Literals not allowed as subjects in data", -1, -1);
+		return q;
+	}
+
+	/**
+	 * Add all where attributes from the Where Handler argument.
+	 * 
+	 * @param whereHandler
+	 *            The Where Handler to copy from.
+	 */
+	public UpdateBuilder addAll(WhereHandler whereHandler) {
+		whereProcessor.addAll(whereHandler);
+		return this;
+	}
+
+	/**
+	 * 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 UpdateBuilder addWhere(TriplePath t) throws IllegalArgumentException {
+		whereProcessor.addWhere(t);
+		return this;
+	}
+
+	/**
+	 * 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 UpdateBuilder addWhere(WhereClause<?> whereClause) throws IllegalArgumentException {
+		whereProcessor.addAll(whereClause.getWhereHandler());
+		return this;
+	}
+	/**
+	 * Add an optional triple to the where clause
+	 * 
+	 * @param t
+	 *            The triple 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(TriplePath t) throws IllegalArgumentException {
+		whereProcessor.addOptional(t);
+		return this;
+	}
+
+	/**
+	 * Add the contents of a where handler as an optional statement.
+	 * 
+	 * @param whereHandler
+	 *            The where handler to use as the optional statement.
+	 */
+	public UpdateBuilder addOptional(WhereHandler whereHandler) {
+		whereProcessor.addOptional(whereHandler);
+		return this;
+	}
+
+	/**
+	 * Add an expression string as a filter.
+	 * 
+	 * @param expression
+	 *            The expression string to add.
+	 * @return The Builder for chaining.
+	 * @throws ParseException
+	 *             If the expression can not be parsed.
+	 */
+	public UpdateBuilder addFilter(String expression) throws ParseException {
+		whereProcessor.addFilter(expression);
+		return this;
+	}
+
+	/**
+	 * Add a subquery to the where clause.
+	 * 
+	 * @param subQuery
+	 *            The sub query to add.
+	 * @return The Builder for chaining.
+	 */
+	public UpdateBuilder addSubQuery(AbstractQueryBuilder<?> subQuery) {
+		whereProcessor.addSubQuery(subQuery);
+		return this;
+	}
+
+	/**
+	 * Add a union to the where clause.
+	 * 
+	 * @param subQuery
+	 *            The subquery to add as the union.
+	 * @return The Builder for chaining.
+	 */
+	public UpdateBuilder addUnion(AbstractQueryBuilder<?> subQuery) {
+		whereProcessor.addUnion(subQuery);
+		return this;
+	}
+
+	/**
+	 * Add a graph to the where clause.
+	 * 
+	 * @param graph
+	 *            The name of the graph.
+	 * @param subQuery
+	 *            The where handler that defines the graph.
+	 */
+	public UpdateBuilder addGraph(Node graph, WhereHandler subQuery) {
+		whereProcessor.addGraph(graph, subQuery);
+		return this;
+	}
+
+	/**
+	 * Add a binding to the where clause.
+	 * 
+	 * @param expr
+	 *            The expression to bind.
+	 * @param var
+	 *            The variable to bind it to.
+	 */
+	public UpdateBuilder addBind(Expr expr, Var var) {
+		whereProcessor.addBind(expr, var);
+		return this;
+	}
+
+	/**
+	 * Add a binding to the where clause.
+	 * 
+	 * @param expression
+	 *            The expression to bind.
+	 * @param var
+	 *            The variable to bind it to.
+	 * @throws ParseException
+	 */
+	public UpdateBuilder addBind(String expression, Var var) throws ParseException {
+		whereProcessor.addBind(expression, var);
+		return this;
+	}
+
+	/**
+	 * 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>
+	 * </p>
+	 * 
+	 * @param objs
+	 *            the list of objects for the list.
+	 * 
+	 * @param objs
+	 *            the list of objects for the list.
+	 * @return the first blank node in the list.
+	 */
+	public Node list(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(new Triple(lastObject, RDF.first.asNode(), n)));
+			if (i + 1 < objs.length) {
+				Node nextObject = NodeFactory.createBlankNode();
+				addWhere(new TriplePath(new Triple(lastObject, RDF.rest.asNode(), nextObject)));
+				lastObject = nextObject;
+			} else {
+				addWhere(new TriplePath(new Triple(lastObject, RDF.rest.asNode(), RDF.nil.asNode())));
+			}
+
+		}
+
+		return retval;
+	}
+
+	/**
+	 * Adds a triple to the where clause.
+	 * 
+	 * @param t
+	 *            The triple path to add
+	 * @return The Builder for chaining.
+	 */
+	public UpdateBuilder addWhere(Triple t) {
+		return addWhere(new TriplePath(t));
+	}
+
+	/**
+	 * Adds a triple to the where clause.
+	 * 
+	 * @param t
+	 *            The triple to add
+	 * @return The Builder for chaining.
+	 */
+	public UpdateBuilder addWhere(FrontsTriple t) {
+		return addWhere(t.asTriple());
+	}
+
+	/**
+	 * Adds a triple or triple path to the where clause.
+	 * 
+	 * See {@link AbstractQueryBuilder#makeTriplePath} for conversion of the
+	 * param values.
+	 * 
+	 * @param s
+	 *            The subject.
+	 * @param p
+	 *            The predicate.
+	 * @param o
+	 *            The object.
+	 * @return The Builder for chaining.
+	 */
+	public UpdateBuilder addWhere(Object s, Object p, Object o) {
+		return addWhere(new Triple(makeNode(s), makeNode(p), makeNode(o)));
+	}
+
+	/**
+	 * Adds an optional triple to the where clause.
+	 * 
+	 * @param t
+	 *            The triple to add
+	 * @return The Builder for chaining.
+	 */
+	public UpdateBuilder addOptional(Triple t) {
+		return addOptional(new TriplePath(t));
+	}
+
+	/**
+	 * Adds an optional triple as to the where clause.
+	 * 
+	 * @param t
+	 *            The triple to add
+	 * @return The Builder for chaining.
+	 */
+	public UpdateBuilder addOptional(FrontsTriple t) {
+		return addOptional(t.asTriple());
+	}
+
+	/**
+	 * Adds an optional triple or triple path to the where clause.
+	 * 
+	 * See {@link AbstractQueryBuilder#makeTriplePath} for conversion of the
+	 * param values.
+	 * 
+	 * @param s
+	 *            The subject.
+	 * @param p
+	 *            The predicate.
+	 * @param o
+	 *            The object.
+	 * @return The Builder for chaining.
+	 */
+	public UpdateBuilder addOptional(Object s, Object p, Object o) {
+		return addOptional(new Triple(makeNode(s), makeNode(p), makeNode(o)));
+	}
+
+	/**
+	 * Adds an optional group pattern to the where clause.
+	 * 
+	 * @param t
+	 *            The select builder to add as an optional pattern
+	 * @return The Builder for chaining.
+	 */
+	public UpdateBuilder addOptional(AbstractQueryBuilder<?> t) {
+		whereProcessor.addOptional(t.getWhereHandler());
+		return this;
+	}
+
+	/**
+	 * Adds a filter to the where clause
+	 * 
+	 * Use ExprFactory or NodeValue static or the AbstractQueryBuilder.makeExpr
+	 * methods to create the expression.
+	 * 
+	 * @see ExprFactory
+	 * @see org.apache.jena.sparql.expr.NodeValue
+	 * @see AbstractQueryBuilder#makeExpr(String)
+	 * 
+	 * @param expression
+	 *            the expression to evaluate for the filter.
+	 * @return @return The Builder for chaining.
+	 */
+	public UpdateBuilder addFilter(Expr expression) {
+		whereProcessor.addFilter(expression);
+		return this;
+	}
+
+	/**
+	 * Add a graph statement to the query as per
+	 * http://www.w3.org/TR/2013/REC-sparql11
+	 * -query-20130321/#rGraphGraphPattern.
+	 * 
+	 * See {@link AbstractQueryBuilder#makeNode} for conversion of the graph
+	 * param.
+	 * 
+	 * @param graph
+	 *            The iri or variable identifying the graph.
+	 * @param subQuery
+	 *            The graph to add.
+	 * @return This builder for chaining.
+	 */
+	public UpdateBuilder addGraph(Object graph, AbstractQueryBuilder<?> subQuery) {
+		whereProcessor.addGraph(makeNode(graph), subQuery.getWhereHandler());
+		return this;
+	}
+
+	/**
+	 * Add a bind statement to the query *
+	 * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rGraphGraphPattern.
+	 * 
+	 * @param expression
+	 *            The expression to bind to the var.
+	 * @param var
+	 *            The variable to bind to.
+	 * @return This builder for chaining.
+	 */
+	public UpdateBuilder addBind(Expr expression, Object var) {
+		whereProcessor.addBind(expression, makeVar(var));
+		return this;
+	}
+
+	/**
+	 * Add a bind statement to the query
+	 * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rGraphGraphPattern.
+	 * 
+	 * @param expression
+	 *            The expression to bind to the var.
+	 * @param var
+	 *            The variable to bind to.
+	 * @return This builder for chaining.
+	 * @throws ParseException
+	 */
+	public UpdateBuilder addBind(String expression, Object var) throws ParseException {
+		whereProcessor.addBind(expression, makeVar(var));
+		return this;
+	}
+
+	/**
+	 * Add a minus clause to the query.
+	 * 
+	 * https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rMinusGraphPattern
+	 * 
+	 * @param t
+	 *            The select builder to add as a minus pattern
+	 * @return this builder for chaining
+	 */
+	public UpdateBuilder addMinus(AbstractQueryBuilder<?> t) {
+		whereProcessor.addMinus(t);
+		return this;
+	}
+
+	/**
+	 * Specify the graph for all inserts and deletes.
+	 * 
+	 * 
+	 * @See Quad#defaultGraphNodeGenerated
+	 * @param iri
+	 *            the IRI for the graph to use.
+	 * @return this builder for chaining.
+	 */
+	public UpdateBuilder with(Object iri) {
+		if (iri == null) {
+			with = null;
+		}
+		Node n = makeNode(iri);
+		if (n.isLiteral()) {
+			throw new IllegalArgumentException(String.format("IRI '%s' must not be a literal", iri));
+		}
+		with = n;
+		return this;
+	}
+
+	/**
+	 * Create a DeleteWhere from the where clause.
+	 * @return a DeleteWhere update.
+	 */
+	public UpdateDeleteWhere buildDeleteWhere()
+	{
+		QuadAcc quadAcc = new QuadAcc( whereProcessor.getQuads().toList() );
+		return new UpdateDeleteWhere( quadAcc );
+	}
+	
+	/**
+	 * Create a DeleteWhere from the where clause.
+	 * @param queryBuilder the query builder to extract the where clause from.
+	 * @return a DeleteWhere update.
+	 */
+	public UpdateDeleteWhere buildDeleteWhere( AbstractQueryBuilder<?> queryBuilder)
+	{	
+		QuadAcc quadAcc = new QuadAcc( new QBQuadHolder( queryBuilder ).getQuads().toList() );
+		return new UpdateDeleteWhere( quadAcc );
+	}
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/WhereHandler.java
----------------------------------------------------------------------
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 b5f04ac..95d8bc7 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
@@ -57,6 +57,15 @@ public class WhereHandler implements Handler {
 	public WhereHandler(Query query) {
 		this.query = query;
 	}
+	
+	/**
+	 * Get the query pattern from this where handler.
+	 * @return the query pattern
+	 */
+	public Element getQueryPattern()
+	{
+		 return query.getQueryPattern();
+	}
 
 	/**
 	 * Add all where attributes from the Where Handler argument.
@@ -273,7 +282,7 @@ public class WhereHandler implements Handler {
 	 *            The sub query to convert
 	 * @return THe converted element.
 	 */
-	private ElementSubQuery makeSubQuery(AbstractQueryBuilder<?> subQuery) {
+	public ElementSubQuery makeSubQuery(AbstractQueryBuilder<?> subQuery) {
 		Query q = new Query();
 		SelectHandler sh = subQuery.getHandlerBlock().getSelectHandler();
 		if (sh != null)
@@ -421,12 +430,18 @@ public class WhereHandler implements Handler {
 		return retval;
 	}
 	
-	public void addMinus( AbstractQueryBuilder<?> t )
+	/**
+	 * Add a minus operation to the where clause.
+	 * The prolog will be updated with the prefixes from the abstract query builder.
+	 * 
+	 * @param qb the abstract builder that defines the data to subtract.
+	 */
+	public void addMinus( AbstractQueryBuilder<?> qb )
 	{
 		PrologHandler ph = new PrologHandler(query);
-		ph.addPrefixes( t.getPrologHandler().getPrefixes() );
+		ph.addPrefixes( qb.getPrologHandler().getPrefixes() );
 		ElementGroup clause = getClause();
-		ElementMinus minus = new ElementMinus(t.getWhereHandler().getClause());
+		ElementMinus minus = new ElementMinus(qb.getWhereHandler().getClause());
 		clause.addElement(minus);
 	}
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/PrefixHandler.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/PrefixHandler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/PrefixHandler.java
new file mode 100644
index 0000000..5713e04
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/PrefixHandler.java
@@ -0,0 +1,115 @@
+/*
+ * 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.Map;
+
+import org.apache.jena.arq.querybuilder.ExprFactory;
+import org.apache.jena.shared.PrefixMapping ;
+
+/**
+ * The prefix handler for the updatebuilder class
+ *
+ */
+public class PrefixHandler {
+
+	// the prefix mapping we are handling
+	private final PrefixMapping pMap;
+
+	/**
+	 * Constructor.
+	 * <b>May modify the contents of the provided prefix mapping</b>
+	 * @param pMap The prefix map to handle.
+	 */
+	public PrefixHandler(PrefixMapping pMap) {
+		this.pMap = pMap;
+	}
+	
+	/**
+	 * Constructor.  Creates and empty prefix mapping
+	 */
+	public PrefixHandler() {
+		this.pMap = PrefixMapping.Factory.create();
+	}
+
+	/**
+	 * get the canonical prefix name.  
+	 * 
+	 * Removes ':' from the end of the name if present.
+	 * 
+	 * @param x The prefix name
+	 * @return The prefix name with the trialing ':' removed.
+	 */
+	private static String canonicalPfx(String x) {
+		if (x.endsWith(":"))
+			return x.substring(0, x.length() - 1);
+		return x;
+	}
+
+	
+	/**
+	 * Add a prefix to the prefix mapping.
+	 * @param pfx The prefix to add.
+	 * @param uri The uri to resolve the prefix to.
+	 */
+	public void addPrefix(String pfx, String uri) {
+		pMap.setNsPrefix(canonicalPfx(pfx), uri);
+	}
+	
+	/**
+	 * Clear the prefix mapping.
+	 */
+	public void clearPrefixes() {
+		pMap.clearNsPrefixMap();
+	}
+
+	/**
+	 * Add the map of prefixes to the query prefixes.
+	 * @param prefixes The map of prefixs to URIs.
+	 */
+	public void addPrefixes(Map<String, String> prefixes) {
+		for (Map.Entry<String, String> e : prefixes.entrySet()) {
+			addPrefix(e.getKey(), e.getValue());
+		}
+	}
+	
+	/**
+	 * Get the prefix mapping
+	 * @return the prefix mapping object.
+	 */
+	public PrefixMapping getPrefixes() {
+		return pMap;
+	}
+	
+	/**
+	 * Get the expression factory based on the prefix mapping.
+	 * @return an Expression Factory.
+	 */
+	public ExprFactory getExprFactory() {
+		return new ExprFactory( pMap );
+	}
+
+	/**
+	 * Add prefixes from a prefix mapping.
+	 * @param prefixes THe prefix mapping to add from.
+	 */
+	public void addPrefixes(PrefixMapping prefixes) {
+		pMap.setNsPrefixes(prefixes);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QBQuadHolder.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QBQuadHolder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QBQuadHolder.java
new file mode 100644
index 0000000..d6584dd
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QBQuadHolder.java
@@ -0,0 +1,79 @@
+/*
+ * 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.Map;
+
+import org.apache.jena.arq.querybuilder.AbstractQueryBuilder;
+import org.apache.jena.graph.Node;
+import org.apache.jena.query.Query;
+import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.util.iterator.ExtendedIterator;
+
+/**
+ * An QuadHolder that manages AbstractQueryBuilder data.
+ *
+ */
+public class QBQuadHolder implements QuadHolder {
+
+	private final AbstractQueryBuilder<?> qb;
+	private Node defaultGraphName;
+	
+	/**
+	 * Constructor.
+	 * @param graph the default graph name for the triples
+	 * @param qb the AbstractQueryBuilder that is providing the triples.
+	 */
+	public QBQuadHolder( Node graph, AbstractQueryBuilder<?> qb )
+	{
+		this.qb = qb;
+		this.defaultGraphName = graph;
+	}
+	
+	/**
+	 * Constructor.
+	 *  Uses  Quad.defaultGraphNodeGenerated for the graph name.
+	 * 
+	 * @see  Quad#defaultGraphNodeGenerated 
+	 * @param qb the AbstractQueryBuilder that is providing the triples.
+	 */
+	public QBQuadHolder( AbstractQueryBuilder<?> qb )
+	{
+		this( Quad.defaultGraphNodeGenerated, qb );
+	}
+	
+	@Override
+	public ExtendedIterator<Quad> getQuads() {
+		Query q = qb.build();
+		QuadIteratorBuilder builder = new QuadIteratorBuilder(defaultGraphName);
+		q.getQueryPattern().visit(builder);
+		return builder.iter;
+	}
+
+	@Override
+	public QuadHolder setValues(Map<Var, Node> values) {
+		qb.clearValues();
+		for (Map.Entry<Var, Node> entry : values.entrySet())
+		{
+			qb.setVar(entry.getKey(), entry.getValue());
+		}
+		return this;
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QuadHolder.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QuadHolder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QuadHolder.java
new file mode 100644
index 0000000..607898d
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QuadHolder.java
@@ -0,0 +1,46 @@
+/*
+ * 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.Map;
+
+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;
+
+/**
+ * An interface that defines a holder of quads.
+ *
+ */
+public interface QuadHolder {
+
+	/**
+	 * Get an extended iterator over the quads this holder holds.
+	 * @return the extended iterator.
+	 */
+	public ExtendedIterator<Quad> getQuads();
+	
+	/**
+	 * Apply values to the variables in the quads held by this holder.
+	 * May return this holder or a new holder instance.
+	 * @param values the values to set.
+	 * @return a QuadHolder in which the variables have been replaced.
+	 */
+	public QuadHolder setValues(Map<Var, Node> values);
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QuadIteratorBuilder.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QuadIteratorBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QuadIteratorBuilder.java
new file mode 100644
index 0000000..cc7c2ea
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/QuadIteratorBuilder.java
@@ -0,0 +1,180 @@
+/*
+ * 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.function.Function;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.query.Query;
+import org.apache.jena.query.QueryParseException;
+import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.sparql.core.TriplePath;
+import org.apache.jena.sparql.syntax.Element;
+import org.apache.jena.sparql.syntax.ElementAssign;
+import org.apache.jena.sparql.syntax.ElementBind;
+import org.apache.jena.sparql.syntax.ElementData;
+import org.apache.jena.sparql.syntax.ElementDataset;
+import org.apache.jena.sparql.syntax.ElementExists;
+import org.apache.jena.sparql.syntax.ElementFilter;
+import org.apache.jena.sparql.syntax.ElementGroup;
+import org.apache.jena.sparql.syntax.ElementMinus;
+import org.apache.jena.sparql.syntax.ElementNamedGraph;
+import org.apache.jena.sparql.syntax.ElementNotExists;
+import org.apache.jena.sparql.syntax.ElementOptional;
+import org.apache.jena.sparql.syntax.ElementPathBlock;
+import org.apache.jena.sparql.syntax.ElementService;
+import org.apache.jena.sparql.syntax.ElementSubQuery;
+import org.apache.jena.sparql.syntax.ElementTriplesBlock;
+import org.apache.jena.sparql.syntax.ElementUnion;
+import org.apache.jena.sparql.syntax.ElementVisitor;
+import org.apache.jena.util.iterator.ExtendedIterator;
+import org.apache.jena.util.iterator.WrappedIterator;
+
+/**
+ * A class to construct a quad iterator from the elements.
+ *
+ */
+class QuadIteratorBuilder implements ElementVisitor {
+	// the default graph name
+	private final Node defaultGraph;
+	// the extended iterator we will add to.
+	ExtendedIterator<Quad> iter = WrappedIterator.emptyIterator();
+	
+	// a function to map triples to quads using the default graph name.
+	private Function<Triple,Quad> MAP = 
+		new Function<Triple,Quad>(){
+	
+		@Override
+		public Quad apply(Triple triple) {
+			return new Quad( defaultGraph, triple );
+		}
+	};
+	
+	/**
+	 * Constructor.
+	 * @param defaultGraph the default graph name.
+	 */
+	QuadIteratorBuilder(Node defaultGraph)
+	{
+		this.defaultGraph = defaultGraph;
+	}
+	
+	
+	@Override
+	public void visit(ElementTriplesBlock el) {
+		iter = iter.andThen( WrappedIterator.create(el.getPattern().getList().iterator())
+		.mapWith( MAP ));
+	}
+
+	@Override
+	public void visit(ElementPathBlock el) {
+		for (TriplePath pth : el.getPattern().getList())
+		{
+			if ( ! pth.isTriple())
+			{
+	            throw new QueryParseException("Paths not permitted in data quad", -1, -1) ;   
+			}
+		}
+		iter = iter.andThen( 
+				WrappedIterator.create(el.getPattern().getList().iterator())
+				.mapWith( pth -> pth.asTriple() )
+				.mapWith( MAP ));
+	}
+
+	@Override
+	public void visit(ElementFilter el) {
+        throw new QueryParseException("Paths not permitted in data quad", -1, -1) ;   
+	}
+
+	@Override
+	public void visit(ElementAssign el) {
+        throw new QueryParseException("element assignment not permitted in data quad", -1, -1) ;   
+	}
+
+	@Override
+	public void visit(ElementBind el) {
+        throw new QueryParseException("bind not permitted in data quad", -1, -1) ;   
+		
+	}
+
+	@Override
+	public void visit(ElementData el) {
+        throw new QueryParseException("element data not permitted in data quad", -1, -1) ;   
+	}
+
+	@Override
+	public void visit(ElementUnion el) {
+		for (Element e : el.getElements())
+		{
+			e.visit( this );
+		}
+	}
+
+	@Override
+	public void visit(ElementOptional el) {
+        throw new QueryParseException("optional not permitted in data quad", -1, -1) ;   
+	}
+
+	@Override
+	public void visit(ElementGroup el) {
+		for (Element e : el.getElements())
+		{
+			e.visit( this );
+		}
+	}
+
+	@Override
+	public void visit(ElementDataset el) {
+		iter = iter.andThen(el.getDataset().find());			
+	}
+
+	@Override
+	public void visit(ElementNamedGraph el) {
+		QuadIteratorBuilder bldr = new QuadIteratorBuilder( el.getGraphNameNode());
+		el.getElement().visit(bldr);
+		iter = iter.andThen( bldr.iter );
+	}
+
+	@Override
+	public void visit(ElementExists el) {
+        throw new QueryParseException("exists not permitted in data quad", -1, -1) ;   
+	}
+
+	@Override
+	public void visit(ElementNotExists el) {
+        throw new QueryParseException("not exists not permitted in data quad", -1, -1) ;   
+	}
+
+	@Override
+	public void visit(ElementMinus el) {
+		throw new QueryParseException("minus not permitted in data quad", -1, -1) ;		
+	}
+
+	@Override
+	public void visit(ElementService el) {
+		throw new QueryParseException("service not permitted in data quad", -1, -1) ;		
+	}
+
+	@Override
+	public void visit(ElementSubQuery el) {
+		Query q = el.getQuery();
+		q.getQueryPattern().visit( this );
+	}
+	
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/SingleQuadHolder.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/SingleQuadHolder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/SingleQuadHolder.java
new file mode 100644
index 0000000..234de60
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/SingleQuadHolder.java
@@ -0,0 +1,97 @@
+/*
+ * 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.Map;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+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.SingletonIterator;
+
+/**
+ * A QuadHolder implementation for a single quad.
+ */
+public class SingleQuadHolder implements QuadHolder{
+
+	private Quad quad;
+	private Quad updated;
+
+	/**
+	 * Constructor for a single quad.
+	 * @param quad the quad to hold.
+	 */
+	public SingleQuadHolder( Quad quad )
+	{
+		this.quad = quad;
+	}
+
+	/**
+	 * Constructor from a triple
+	 * Uses  Quad.defaultGraphNodeGenerated for the graph name.
+	 * 
+	 * @see  Quad#defaultGraphNodeGenerated 
+	 * @param triple the triple to convert to a quad.
+	 */
+	public SingleQuadHolder( Triple triple )
+	{
+		this.quad = new Quad( Quad.defaultGraphNodeGenerated, triple );
+	}
+
+	
+	/**
+	 * Constructor from a triple
+	 * @param graph the graph name to use for the  triple 
+	 * @param triple the triple to convert to a quad.
+	 */
+	public SingleQuadHolder( Node graph, Triple triple )
+	{
+		this.quad = new Quad( graph, triple );
+	}
+	
+	@Override
+	public ExtendedIterator<Quad> getQuads() {
+		return new SingletonIterator<Quad>(updated==null?quad:updated);
+	}
+
+	// convert variable if in map
+	private Node mapValue( Node n, Map<Var, Node> values)
+	{
+		Node retval = null;
+		if (n.isVariable())
+		{
+			Var v = Var.alloc(n);
+			retval = values.get(v);
+		}
+		return retval==null?n:retval;
+	}
+	
+	@Override
+	public QuadHolder setValues(Map<Var, Node> values) {
+		updated = new Quad( 
+				mapValue( quad.getGraph(), values),
+				mapValue( quad.getSubject(), values),
+				mapValue( quad.getPredicate(), values),
+				mapValue( quad.getObject(), values)
+				);
+		return this;
+	}
+
+	
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/WhereProcessor.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/WhereProcessor.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/WhereProcessor.java
new file mode 100644
index 0000000..b6e40e4
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/updatebuilder/WhereProcessor.java
@@ -0,0 +1,433 @@
+/*
+ * 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.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.jena.arq.querybuilder.AbstractQueryBuilder;
+import org.apache.jena.arq.querybuilder.clauses.SelectClause;
+import org.apache.jena.arq.querybuilder.handlers.WhereHandler;
+import org.apache.jena.arq.querybuilder.rewriters.ElementRewriter;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.query.Query;
+import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.sparql.core.TriplePath;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.expr.Expr;
+import org.apache.jena.sparql.lang.sparql_11.ParseException;
+import org.apache.jena.sparql.syntax.*;
+import org.apache.jena.sparql.util.ExprUtils;
+import org.apache.jena.util.iterator.ExtendedIterator;
+import org.apache.jena.util.iterator.NiceIterator;
+import org.apache.jena.vocabulary.RDF;
+
+/**
+ * The where processor. Generally handles update where clause.
+ * 
+ * @see <a href=
+ *      "http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rGroupGraphPattern">
+ *      SPARQL 11 Query Language - Group Graph Pattern</a>
+ *
+ */
+public class WhereProcessor implements QuadHolder {
+
+	private Element whereClause;
+	private final PrefixHandler prefixHandler;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param prefixHandler
+	 *            the prefix handler to use.
+	 */
+	public WhereProcessor(PrefixHandler prefixHandler) {
+		this.prefixHandler = prefixHandler;
+	}
+
+	/**
+	 * True if there are no elements in the where processor.
+	 * 
+	 * @return true if there are no elements.
+	 */
+	public boolean isEmpty() {
+		return whereClause == null || (whereClause instanceof ElementGroup && ((ElementGroup) whereClause).isEmpty());
+	}
+
+	@Override
+	public ExtendedIterator<Quad> getQuads() {
+		return getQuads( Quad.defaultGraphNodeGenerated);
+	}
+	
+	public ExtendedIterator<Quad> getQuads( Node defaultGraphName ) {
+		if (isEmpty())
+		{
+			return NiceIterator.emptyIterator();
+		}
+		QuadIteratorBuilder builder = new QuadIteratorBuilder(defaultGraphName);
+		whereClause.visit(builder);
+		return builder.iter;
+	}
+	/**
+	 * Add all where attributes from the Where Handler argument.
+	 * 
+	 * @param whereHandler
+	 *            The Where Handler to copy from.
+	 */
+	public void addAll(WhereHandler whereHandler) {
+
+		Element e = whereHandler.getQueryPattern();
+		if (e != null) {
+			// clone the Element
+			ElementRewriter rewriter = new ElementRewriter(Collections.emptyMap());
+			e.visit(rewriter);
+			Element clone = rewriter.getResult();
+
+			if (whereClause == null) {
+				whereClause = clone;
+			} else {
+				ElementGroup eg = null;
+				if (whereClause instanceof ElementGroup) {
+					eg = (ElementGroup) whereClause;
+				} else {
+					eg = new ElementGroup();
+					eg.addElement(whereClause);
+				}
+				if (clone instanceof ElementGroup) {
+					for (Element ele : ((ElementGroup) clone).getElements()) {
+						eg.addElement(ele);
+					}
+				} else {
+					eg.addElement(clone);
+				}
+				whereClause = eg;
+			}
+		}
+	}
+
+	/**
+	 * Get the element group for the clause. if The element group is not set,
+	 * create and set it.
+	 * 
+	 * Public for ExprFactory use.
+	 * 
+	 * @return The element group.
+	 */
+	public ElementGroup getClause() {
+		Element e = whereClause;
+		if (e == null) {
+			e = new ElementGroup();
+			whereClause = e;
+		}
+		if (e instanceof ElementGroup) {
+			return (ElementGroup) e;
+		}
+
+		ElementGroup eg = new ElementGroup();
+		eg.addElement(e);
+		whereClause = eg;
+		return eg;
+	}
+
+	/**
+	 * Test that a triple is valid. Throws an IllegalArgumentException if the
+	 * triple is not valid.
+	 * 
+	 * @param t
+	 *            The trip to test.
+	 */
+	private static void testTriple(TriplePath t) {
+		// verify Triple is valid
+		boolean validSubject = t.getSubject().isURI() || t.getSubject().isBlank() || t.getSubject().isVariable()
+				|| t.getSubject().equals(Node.ANY);
+		boolean validPredicate;
+
+		if (t.isTriple()) {
+			validPredicate = t.getPredicate().isURI() || t.getPredicate().isVariable()
+					|| t.getPredicate().equals(Node.ANY);
+		} else {
+			validPredicate = t.getPath() != null;
+		}
+
+		boolean validObject = t.getObject().isURI() || t.getObject().isLiteral() || t.getObject().isBlank()
+				|| t.getObject().isVariable() || t.getObject().equals(Node.ANY);
+
+		if (!validSubject || !validPredicate || !validObject) {
+			StringBuilder sb = new StringBuilder();
+			if (!validSubject) {
+				sb.append(String.format("Subject (%s) must be a URI, blank, variable, or a wildcard. %n",
+						t.getSubject()));
+			}
+			if (!validPredicate) {
+				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",
+						t.getObject()));
+			}
+			if (!validSubject || !validPredicate) {
+				sb.append(String.format("Is a prefix missing?  Prefix must be defined before use. %n"));
+			}
+			throw new IllegalArgumentException(sb.toString());
+		}
+	}
+
+	/**
+	 * 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(TriplePath t) throws IllegalArgumentException {
+		testTriple(t);
+		ElementGroup eg = getClause();
+		List<Element> lst = eg.getElements();
+		if (lst.isEmpty()) {
+			ElementPathBlock epb = new ElementPathBlock();
+			epb.addTriple(t);
+			eg.addElement(epb);
+		} else {
+			Element e = lst.get(lst.size() - 1);
+			if (e instanceof ElementTriplesBlock && t.isTriple()) {
+				ElementTriplesBlock etb = (ElementTriplesBlock) e;
+				etb.addTriple(t.asTriple());
+			} else if (e instanceof ElementPathBlock) {
+				ElementPathBlock epb = (ElementPathBlock) e;
+				epb.addTriple(t);
+			} else {
+				ElementPathBlock etb = new ElementPathBlock();
+				etb.addTriple(t);
+				eg.addElement(etb);
+			}
+
+		}
+	}
+
+	/**
+	 * 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(TriplePath t) throws IllegalArgumentException {
+		testTriple(t);
+		ElementPathBlock epb = new ElementPathBlock();
+		epb.addTriple(t);
+		ElementOptional opt = new ElementOptional(epb);
+		getClause().addElement(opt);
+	}
+
+	/**
+	 * Add the contents of a where handler as an optional statement.
+	 * 
+	 * @param whereHandler
+	 *            The where handler to use as the optional statement.
+	 */
+	public void addOptional(WhereHandler whereHandler) {
+		getClause().addElement(new ElementOptional(whereHandler.getClause()));
+	}
+
+	/**
+	 * Add an expression string as a filter.
+	 * 
+	 * @param expression
+	 *            The expression string to add.
+	 * @throws ParseException
+	 *             If the expression can not be parsed.
+	 */
+	public void addFilter(String expression) throws ParseException {
+		getClause().addElement(new ElementFilter(parseExpr(expression)));
+	}
+
+	private Expr parseExpr(String expression) {
+		Query query = new Query();
+		query.setPrefixMapping(prefixHandler.getPrefixes());
+		return ExprUtils.parse(query, expression, true);
+
+	}
+
+	/**
+	 * add an expression as a filter.
+	 * 
+	 * @param expr
+	 *            The expression to add.
+	 */
+	public void addFilter(Expr expr) {
+		getClause().addElement(new ElementFilter(expr));
+	}
+
+	/**
+	 * Add a subquery to the where clause.
+	 * 
+	 * @param subQuery
+	 *            The sub query to add.
+	 */
+	public void addSubQuery(AbstractQueryBuilder<?> subQuery) {
+		getClause().addElement(subQuery.asSubQuery());
+	}
+
+	/**
+	 * Add a union to the where clause.
+	 * 
+	 * @param subQuery
+	 *            The subquery to add as the union.
+	 */
+	public void addUnion(AbstractQueryBuilder<?> subQuery) {
+		ElementUnion union = null;
+		ElementGroup clause = getClause();
+		// if the last element is a union make sure we add to it.
+		if (!clause.isEmpty()) {
+			Element lastElement = clause.getElements().get(clause.getElements().size() - 1);
+			if (lastElement instanceof ElementUnion) {
+				union = (ElementUnion) lastElement;
+			} else {
+				// clauses is not empty and is not a union so it is the left
+				// side of the union.
+				union = new ElementUnion();
+				union.addElement(clause);
+				whereClause = union;
+			}
+		} else {
+			// add the union as the first element in the clause.
+			union = new ElementUnion();
+			clause.addElement(union);
+		}
+		// if there are projected vars then do a full blown subquery
+		// otherwise just add the clause.
+		if (subQuery instanceof SelectClause && ((SelectClause<?>) subQuery).getVars().size() > 0) {
+			union.addElement(subQuery.asSubQuery());
+		} else {
+			prefixHandler.addPrefixes(subQuery.getPrologHandler().getPrefixes());
+			union.addElement(subQuery.getWhereHandler().getClause());
+		}
+
+	}
+
+	/**
+	 * Add a graph to the where clause.
+	 * 
+	 * @param graph
+	 *            The name of the graph.
+	 * @param subQuery
+	 *            The where handler that defines the graph.
+	 */
+	public void addGraph(Node graph, WhereHandler subQuery) {
+		getClause().addElement(new ElementNamedGraph(graph, subQuery.getClause()));
+	}
+
+	/**
+	 * Add a binding to the where clause.
+	 * 
+	 * @param expr
+	 *            The expression to bind.
+	 * @param var
+	 *            The variable to bind it to.
+	 */
+	public void addBind(Expr expr, Var var) {
+		getClause().addElement(new ElementBind(var, expr));
+	}
+
+	/**
+	 * Add a binding to the where clause.
+	 * 
+	 * @param expression
+	 *            The expression to bind.
+	 * @param var
+	 *            The variable to bind it to.
+	 * @throws ParseException
+	 */
+	public void addBind(String expression, Var var) throws ParseException {
+		getClause().addElement(new ElementBind(var, parseExpr(expression)));
+	}
+
+	/**
+	 * replace the vars in the expressions with the nodes in the values map.
+	 * Vars not listed in the values map are not changed.
+	 * 
+	 * Will return null if the whereClause is null.
+	 * 
+	 * @param values
+	 *            the value map to use
+	 * @return A new Element instance with the values changed.
+	 */
+	public Element setVars(Map<Var, Node> values) {
+		if (values.isEmpty() || whereClause == null) {
+			return whereClause;
+		}
+		ElementRewriter r = new ElementRewriter(values);
+		whereClause.visit(r);
+		return r.getResult();
+
+	}
+	
+	@Override
+	public QuadHolder setValues(Map<Var, Node> values)
+	{
+		setVars( values );
+		return this;
+	}
+
+	/**
+	 * Create a list node from a list of objects as per RDF Collections.
+	 * 
+	 * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#collections
+	 * 
+	 * @param objs
+	 *            the list of objects for the list.
+	 * @return the first blank node in the list.
+	 */
+	public Node list(Object... objs) {
+		Node retval = NodeFactory.createBlankNode();
+		Node lastObject = retval;
+		for (int i = 0; i < objs.length; i++) {
+			Node n = AbstractQueryBuilder.makeNode(objs[i], prefixHandler.getPrefixes());
+			addWhere(new TriplePath(new Triple(lastObject, RDF.first.asNode(), n)));
+			if (i + 1 < objs.length) {
+				Node nextObject = NodeFactory.createBlankNode();
+				addWhere(new TriplePath(new Triple(lastObject, RDF.rest.asNode(), nextObject)));
+				lastObject = nextObject;
+			} else {
+				addWhere(new TriplePath(new Triple(lastObject, RDF.rest.asNode(), RDF.nil.asNode())));
+			}
+
+		}
+
+		return retval;
+	}
+
+	/**
+	 * Add a minus operation to the where clause.
+	 * The prefixes will be updated with the prefixes from the abstract query builder.
+	 * 
+	 * @param qb the abstract builder that defines the data to subtract.
+	 */
+	public void addMinus(AbstractQueryBuilder<?> qb) {
+		prefixHandler.addPrefixes(qb.getPrologHandler().getPrefixes());
+		ElementGroup clause = getClause();
+		ElementMinus minus = new ElementMinus(qb.getWhereHandler().getClause());
+		clause.addElement(minus);
+	}
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/7d96286e/jena-extras/jena-querybuilder/src/test/java/Example10.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/test/java/Example10.java b/jena-extras/jena-querybuilder/src/test/java/Example10.java
new file mode 100644
index 0000000..7acbd7c
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/test/java/Example10.java
@@ -0,0 +1,104 @@
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.jena.datatypes.xsd.XSDDatatype;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.query.Dataset;
+import org.apache.jena.query.DatasetFactory;
+import org.apache.jena.rdf.model.Literal;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.ModelFactory;
+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.update.UpdateAction;
+import org.apache.jena.update.UpdateFactory;
+import org.apache.jena.update.UpdateRequest;
+import org.apache.jena.vocabulary.DCTypes;
+import org.apache.jena.vocabulary.DC_11;
+import org.junit.Test;
+
+public class Example10 {
+
+	/**
+	 * 	Example 10: 
+	 * 
+	 *  @see https://www.w3.org/TR/sparql11-update/#example_10
+	 */
+	@Test
+	public void example10()
+	{
+
+		Resource book1 = ResourceFactory.createResource( "http://example/book1" );
+		Resource book3 = ResourceFactory.createResource( "http://example/book3" );
+		Resource book4 = ResourceFactory.createResource( "http://example/book4" );
+		
+		Literal d1996 = ResourceFactory.createTypedLiteral("1996-01-01T00:00:00-02:00", XSDDatatype.XSDdateTime);
+		
+		Node graphName1 = NodeFactory.createURI("http://example/bookStore");
+		Node graphName2 = NodeFactory.createURI("http://example/bookStore2");
+		
+		Model m1 = ModelFactory.createDefaultModel();
+		m1.add( book1, DC_11.title, "Fundamentals of Compiler Design");
+		m1.add( book1, DC_11.date, d1996 );
+		m1.add( book1, DC_11.date, DCTypes.PhysicalObject );
+			
+		m1.add( book3, DC_11.title, "SPARQL 1.1 Tutorial" );
+		
+		Model m2 = ModelFactory.createDefaultModel();
+		m2.add( book4, DC_11.title, "SPARQL 1.1 Tutorial" );
+		
+		Dataset ds = DatasetFactory.create();
+		ds.addNamedModel(graphName1.getURI(), m1);
+		ds.addNamedModel(graphName2.getURI(), m2);
+	
+		String s = "PREFIX dc:  <http://purl.org/dc/elements/1.1/>\n"
+				+ "PREFIX dcmitype: <http://purl.org/dc/dcmitype/>\n"
+				+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n"
+				+ "INSERT\n"
+				+ "  { GRAPH <http://example/bookStore2> { ?book ?p ?v } }\n"
+				+ "WHERE\n"
+				+ "  { GRAPH  <http://example/bookStore>\n"
+				+ "     { ?book dc:date ?date .\n"
+				+ "       FILTER ( ?date < \"2000-01-01T00:00:00-02:00\"^^xsd:dateTime )\n"
+				+ "       ?book ?p ?v\n"
+				+ "     }"
+				+ "  } ;\n\n"
+				+ "WITH <http://example/bookStore>\n"
+				+ "DELETE\n"
+				+ " { ?book ?p ?v }\n"
+				+ "WHERE\n"
+				+ " { ?book dc:date ?date ;\n"
+				+ "         dc:type dcmitype:PhysicalObject .\n"
+				+ "   FILTER ( ?date < \"2000-01-01T00:00:00-02:00\"^^xsd:dateTime )\n"
+				+ "   ?book ?p ?v\n"
+				+ " } ";
+		UpdateRequest req  = UpdateFactory.create(s);
+		
+		System.out.println( req );
+		
+		UpdateAction.execute( req, ds );
+		
+		m1 = ds.getNamedModel( graphName1.getURI());
+		assertEquals( "DELETE failed", 1, m1.listStatements().toList().size());
+
+		assertTrue( m1.contains( book3, DC_11.title, "SPARQL 1.1 Tutorial"));
+
+		
+		m2 = ds.getNamedModel( graphName2.getURI());
+		assertEquals( "Insert failed", 4, m2.listStatements().toList().size());
+
+
+		assertEquals( 3, m1.listStatements( book1, null, (RDFNode)null).toList().size());
+		assertTrue( m2.contains( book1, DC_11.title, "Fundamentals of Compiler Design"));
+		assertTrue( m2.contains( book1, DC_11.date, d1996 ));
+		assertTrue( m2.contains( book1, DC_11.date, DCTypes.PhysicalObject ));
+		
+		assertEquals( 1, m1.listStatements( book4, null, (RDFNode)null).toList().size());
+		assertTrue( m1.contains( book4, DC_11.title, "SPARQL 1.1 Tutorial"));
+		
+	}
+}


[5/6] jena git commit: Merge branch 'requestBuilder'. Fixes JENA-1352

Posted by cl...@apache.org.
Merge branch 'requestBuilder'.  Fixes JENA-1352

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

Branch: refs/heads/master
Commit: 7043d34435ca1ffff20f738c55035aa6994230f7
Parents: e79199a 14fb23e
Author: Claude Warren <cl...@apache.org>
Authored: Sun Jun 4 12:26:30 2017 +0100
Committer: Claude Warren <cl...@apache.org>
Committed: Sun Jun 4 12:27:49 2017 +0100

----------------------------------------------------------------------
 .../arq/querybuilder/AbstractQueryBuilder.java  |    5 +
 .../jena/arq/querybuilder/UpdateBuilder.java    | 1027 ++++++++++++++++++
 .../arq/querybuilder/handlers/WhereHandler.java |   23 +-
 .../updatebuilder/PrefixHandler.java            |  115 ++
 .../updatebuilder/QBQuadHolder.java             |   79 ++
 .../querybuilder/updatebuilder/QuadHolder.java  |   46 +
 .../updatebuilder/QuadIteratorBuilder.java      |  180 +++
 .../updatebuilder/SingleQuadHolder.java         |   97 ++
 .../updatebuilder/WhereProcessor.java           |  433 ++++++++
 .../arq/querybuilder/SelectBuilderTest.java     |    2 -
 .../querybuilder/UpdateBuilderExampleTests.java |  659 +++++++++++
 .../arq/querybuilder/UpdateBuilderTest.java     |  411 +++++++
 12 files changed, 3071 insertions(+), 6 deletions(-)
----------------------------------------------------------------------



[4/6] jena git commit: Removed extraneous test class

Posted by cl...@apache.org.
Removed extraneous test class

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

Branch: refs/heads/master
Commit: 14fb23e49e9aaf5e9522be31a5b4d8071f3a6b5d
Parents: c099281
Author: Claude Warren <cl...@apache.org>
Authored: Sun Jun 4 12:16:39 2017 +0100
Committer: Claude Warren <cl...@apache.org>
Committed: Sun Jun 4 12:16:39 2017 +0100

----------------------------------------------------------------------
 .../src/test/java/Example10.java                | 104 -------------------
 1 file changed, 104 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/14fb23e4/jena-extras/jena-querybuilder/src/test/java/Example10.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/test/java/Example10.java b/jena-extras/jena-querybuilder/src/test/java/Example10.java
deleted file mode 100644
index 7acbd7c..0000000
--- a/jena-extras/jena-querybuilder/src/test/java/Example10.java
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.apache.jena.datatypes.xsd.XSDDatatype;
-import org.apache.jena.graph.Node;
-import org.apache.jena.graph.NodeFactory;
-import org.apache.jena.query.Dataset;
-import org.apache.jena.query.DatasetFactory;
-import org.apache.jena.rdf.model.Literal;
-import org.apache.jena.rdf.model.Model;
-import org.apache.jena.rdf.model.ModelFactory;
-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.update.UpdateAction;
-import org.apache.jena.update.UpdateFactory;
-import org.apache.jena.update.UpdateRequest;
-import org.apache.jena.vocabulary.DCTypes;
-import org.apache.jena.vocabulary.DC_11;
-import org.junit.Test;
-
-public class Example10 {
-
-	/**
-	 * 	Example 10: 
-	 * 
-	 *  @see https://www.w3.org/TR/sparql11-update/#example_10
-	 */
-	@Test
-	public void example10()
-	{
-
-		Resource book1 = ResourceFactory.createResource( "http://example/book1" );
-		Resource book3 = ResourceFactory.createResource( "http://example/book3" );
-		Resource book4 = ResourceFactory.createResource( "http://example/book4" );
-		
-		Literal d1996 = ResourceFactory.createTypedLiteral("1996-01-01T00:00:00-02:00", XSDDatatype.XSDdateTime);
-		
-		Node graphName1 = NodeFactory.createURI("http://example/bookStore");
-		Node graphName2 = NodeFactory.createURI("http://example/bookStore2");
-		
-		Model m1 = ModelFactory.createDefaultModel();
-		m1.add( book1, DC_11.title, "Fundamentals of Compiler Design");
-		m1.add( book1, DC_11.date, d1996 );
-		m1.add( book1, DC_11.date, DCTypes.PhysicalObject );
-			
-		m1.add( book3, DC_11.title, "SPARQL 1.1 Tutorial" );
-		
-		Model m2 = ModelFactory.createDefaultModel();
-		m2.add( book4, DC_11.title, "SPARQL 1.1 Tutorial" );
-		
-		Dataset ds = DatasetFactory.create();
-		ds.addNamedModel(graphName1.getURI(), m1);
-		ds.addNamedModel(graphName2.getURI(), m2);
-	
-		String s = "PREFIX dc:  <http://purl.org/dc/elements/1.1/>\n"
-				+ "PREFIX dcmitype: <http://purl.org/dc/dcmitype/>\n"
-				+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n"
-				+ "INSERT\n"
-				+ "  { GRAPH <http://example/bookStore2> { ?book ?p ?v } }\n"
-				+ "WHERE\n"
-				+ "  { GRAPH  <http://example/bookStore>\n"
-				+ "     { ?book dc:date ?date .\n"
-				+ "       FILTER ( ?date < \"2000-01-01T00:00:00-02:00\"^^xsd:dateTime )\n"
-				+ "       ?book ?p ?v\n"
-				+ "     }"
-				+ "  } ;\n\n"
-				+ "WITH <http://example/bookStore>\n"
-				+ "DELETE\n"
-				+ " { ?book ?p ?v }\n"
-				+ "WHERE\n"
-				+ " { ?book dc:date ?date ;\n"
-				+ "         dc:type dcmitype:PhysicalObject .\n"
-				+ "   FILTER ( ?date < \"2000-01-01T00:00:00-02:00\"^^xsd:dateTime )\n"
-				+ "   ?book ?p ?v\n"
-				+ " } ";
-		UpdateRequest req  = UpdateFactory.create(s);
-		
-		System.out.println( req );
-		
-		UpdateAction.execute( req, ds );
-		
-		m1 = ds.getNamedModel( graphName1.getURI());
-		assertEquals( "DELETE failed", 1, m1.listStatements().toList().size());
-
-		assertTrue( m1.contains( book3, DC_11.title, "SPARQL 1.1 Tutorial"));
-
-		
-		m2 = ds.getNamedModel( graphName2.getURI());
-		assertEquals( "Insert failed", 4, m2.listStatements().toList().size());
-
-
-		assertEquals( 3, m1.listStatements( book1, null, (RDFNode)null).toList().size());
-		assertTrue( m2.contains( book1, DC_11.title, "Fundamentals of Compiler Design"));
-		assertTrue( m2.contains( book1, DC_11.date, d1996 ));
-		assertTrue( m2.contains( book1, DC_11.date, DCTypes.PhysicalObject ));
-		
-		assertEquals( 1, m1.listStatements( book4, null, (RDFNode)null).toList().size());
-		assertTrue( m1.contains( book4, DC_11.title, "SPARQL 1.1 Tutorial"));
-		
-	}
-}