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/24 08:43:45 UTC

[1/2] jena git commit: fix for JENA-1365

Repository: jena
Updated Branches:
  refs/heads/master 5b75b3e16 -> 9093863bf


fix for JENA-1365

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

Branch: refs/heads/master
Commit: b1408fff588a252e794e5e055f8ebeb9034364d7
Parents: 5b75b3e
Author: Claude Warren <cl...@apache.org>
Authored: Sat Jun 24 09:40:50 2017 +0100
Committer: Claude Warren <cl...@apache.org>
Committed: Sat Jun 24 09:40:50 2017 +0100

----------------------------------------------------------------------
 .../arq/querybuilder/handlers/WhereHandler.java | 190 +++++++++++++-
 .../jena/arq/querybuilder/AskBuilderTest.java   |  36 ++-
 .../arq/querybuilder/ConstructBuilderTest.java  |  37 ++-
 .../arq/querybuilder/SelectBuilderTest.java     |  37 ++-
 .../jena/arq/querybuilder/WhereValidator.java   | 205 +++++++++++++++
 .../querybuilder/clauses/WhereClauseTest.java   | 178 +++++++++----
 .../querybuilder/handlers/WhereHandlerTest.java | 257 +++++++++++++++----
 7 files changed, 820 insertions(+), 120 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/b1408fff/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 95d8bc7..97184a7 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
@@ -399,7 +399,12 @@ public class WhereHandler implements Handler {
 
 	@Override
 	public void build() {
-		// no special operations required.
+		/*
+		 * cleanup unoin-of-one and other similar issues.
+		 */
+		BuildElementVisitor visitor = new BuildElementVisitor();
+		getElement().visit(visitor);
+		query.setQueryPattern( visitor.result );
 	}
 
 	/**
@@ -444,4 +449,187 @@ public class WhereHandler implements Handler {
 		ElementMinus minus = new ElementMinus(qb.getWhereHandler().getClause());
 		clause.addElement(minus);
 	}
+	
+	/**
+	 * An element visitor that does an in-place modification of the elements to 
+	 * fix union-of-one and similar issues.
+	 *
+	 */
+	private static class BuildElementVisitor implements ElementVisitor {
+		private Element result;
+
+		@Override
+		public void visit(ElementTriplesBlock el) {
+			// no changes
+			result=el;
+		}
+
+		@Override
+		public void visit(ElementPathBlock el) {
+			// no changes
+			result=el;
+		}
+
+		@Override
+		public void visit(ElementFilter el) {
+			// no changes
+			result=el;
+		}
+
+		@Override
+		public void visit(ElementAssign el) {
+			// no change
+			result=el;
+		}
+
+		@Override
+		public void visit(ElementBind el) {
+			// no change
+			result=el;
+		}
+
+		@Override
+		public void visit(ElementData el) {
+			// no change
+			result=el;
+		}
+
+		private void updateList( List<Element> lst )
+		{
+			 for (int i=0;i<lst.size();i++)
+        	 {
+        		 lst.get(i).visit( this );
+        		 lst.set(i, result);
+        	 }
+		}
+		
+		@Override
+		public void visit(ElementUnion el) {
+			List<Element> lst = el.getElements();
+	         if ( lst.size() <= 1 ) {
+	        	 ElementGroup eg = new ElementGroup();
+	             if ( lst.size() == 1)
+	             {
+	            	 el.getElements().get(0).visit( this );
+	        	   	 eg.addElement(result);
+	             }
+	        	 result = eg;
+	         } else {
+	        	 updateList( lst );
+	        	 result = el;
+	         }
+		}
+
+		@Override
+		public void visit(ElementOptional el) {
+			el.getOptionalElement().visit(this);
+			if (result == el.getOptionalElement())
+			{
+				result = el;
+			} else {
+				result = new ElementOptional( result );
+			}
+		}
+
+		@Override
+		public void visit(ElementGroup el) {
+			List<Element> lst = el.getElements();
+			if (lst.isEmpty())
+			{
+				// noting to do
+				result = el;
+			} else if (lst.size() == 1)
+			{
+				lst.get(0).visit( this );
+				// result is now set properly
+			} else {
+			updateList( lst );
+			result = el;
+			}
+		}
+		
+		@Override
+		public void visit(ElementDataset el) {
+			// noting to do
+			result = el;
+		}
+
+		@Override
+		public void visit(ElementNamedGraph el) {
+			el.getElement().visit( this );
+			if (result == el.getElement())
+			{
+				// nothing to do
+				result = el;
+			}
+			else {
+				result = new ElementNamedGraph( el.getGraphNameNode(), result);
+			}
+		}
+
+		@Override
+		public void visit(ElementExists el) {
+			el.getElement().visit(this);
+			if (result == el.getElement())
+			{
+				// nothing to do
+				result = el;
+			}
+			else {
+				result = new ElementExists( result);
+			}			
+		}
+
+		@Override
+		public void visit(ElementNotExists el) {
+			el.getElement().visit(this);
+			if (result == el.getElement())
+			{
+				// nothing to do
+				result = el;
+			}
+			else {
+				result = new ElementNotExists( result);
+			}
+		}
+
+		@Override
+		public void visit(ElementMinus el) {
+			el.getMinusElement().visit(this);
+			if (result == el.getMinusElement())
+			{
+				// nothing to do
+				result = el;
+			}
+			else {
+				result = new ElementMinus( result);
+			}
+		}
+
+		@Override
+		public void visit(ElementService el) {
+			el.getElement().visit(this);
+			if (result == el.getElement())
+			{
+				// nothing to do
+				result = el;
+			}
+			else {
+				result = new ElementService( el.getServiceNode(), result, el.getSilent());
+			}
+			
+		}
+
+		@Override
+		public void visit(ElementSubQuery el) {
+			WhereHandler other = new WhereHandler( el.getQuery() );
+			other.build();
+			if (other.getElement() != el.getQuery().getQueryPattern())
+			{
+				el.getQuery().setQueryPattern( other.query.getQueryPattern() );
+			}
+			result = el;
+		}
+		
+	}
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/b1408fff/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java
index 53e46c4..1f5b5c5 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AskBuilderTest.java
@@ -22,6 +22,13 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import org.apache.jena.arq.AbstractRegexpBasedTest;
+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.TriplePath;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.syntax.ElementPathBlock;
 import org.apache.jena.vocabulary.RDF ;
 import org.junit.Before;
 import org.junit.Test;
@@ -109,13 +116,32 @@ public class AskBuilderTest extends AbstractRegexpBasedTest {
 	public void testList() {
 		builder
 		 .addWhere( builder.list( "<one>", "?two", "'three'"), "<foo>", "<bar>");
-		String query = builder.buildString();
+		Query query = builder.build();
 		
-		assertContainsRegex(PAREN_OPEN + SPACE + uri("one") + SPACE + var("two") + SPACE + quote("three") + SPACE + PAREN_CLOSE,
-		                    builder.buildString());
 
-		assertContainsRegex(PAREN_CLOSE + "." + SPACE + uri("foo") + SPACE  + uri("bar") + SPACE + CLOSE_CURLY,
-		                    builder.buildString());
+		Node one = NodeFactory.createURI("one");
+		Node two = Var.alloc("two").asNode();
+		Node three = NodeFactory.createLiteral( "three");
+		Node foo = NodeFactory.createURI("foo");
+		Node bar = NodeFactory.createURI("bar");
+		
+		ElementPathBlock epb = new ElementPathBlock();
+		Node firstObject = NodeFactory.createBlankNode();		
+		Node secondObject = NodeFactory.createBlankNode();
+		Node thirdObject = NodeFactory.createBlankNode();
+		
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, RDF.first.asNode(), one)));
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, RDF.rest.asNode(), secondObject)));
+		epb.addTriplePath( new TriplePath( new Triple( secondObject, RDF.first.asNode(), two)));
+		epb.addTriplePath( new TriplePath( new Triple( secondObject, RDF.rest.asNode(), thirdObject)));
+		epb.addTriplePath( new TriplePath( new Triple( thirdObject, RDF.first.asNode(), three)));
+		epb.addTriplePath( new TriplePath( new Triple( thirdObject, RDF.rest.asNode(), RDF.nil.asNode())));
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, foo, bar)));
+		
+		
+		WhereValidator visitor = new WhereValidator( epb );
+		query.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
 	}
 	
 	@Test

http://git-wip-us.apache.org/repos/asf/jena/blob/b1408fff/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java
index c397541..d4c420d 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/ConstructBuilderTest.java
@@ -22,7 +22,13 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import org.apache.jena.arq.AbstractRegexpBasedTest;
+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.TriplePath;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.syntax.ElementPathBlock;
 import org.apache.jena.vocabulary.RDF ;
 import org.junit.Before;
 import org.junit.Test;
@@ -113,13 +119,32 @@ public class ConstructBuilderTest extends AbstractRegexpBasedTest {
 	public void testList() {
 		builder
 		 .addWhere( builder.list( "<one>", "?two", "'three'"), "<foo>", "<bar>");
-		String query = builder.buildString();
-		
-		assertContainsRegex(PAREN_OPEN + SPACE + uri("one") + SPACE + var("two") + SPACE + quote("three") + SPACE + PAREN_CLOSE,
-		                    builder.buildString());
+		Query query = builder.build();
 
-		assertContainsRegex(PAREN_CLOSE + "." + SPACE + uri("foo") + SPACE  + uri("bar") + SPACE + CLOSE_CURLY,
-		                    builder.buildString());
+
+		Node one = NodeFactory.createURI("one");
+		Node two = Var.alloc("two").asNode();
+		Node three = NodeFactory.createLiteral( "three");
+		Node foo = NodeFactory.createURI("foo");
+		Node bar = NodeFactory.createURI("bar");
+		
+		ElementPathBlock epb = new ElementPathBlock();
+		Node firstObject = NodeFactory.createBlankNode();		
+		Node secondObject = NodeFactory.createBlankNode();
+		Node thirdObject = NodeFactory.createBlankNode();
+		
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, RDF.first.asNode(), one)));
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, RDF.rest.asNode(), secondObject)));
+		epb.addTriplePath( new TriplePath( new Triple( secondObject, RDF.first.asNode(), two)));
+		epb.addTriplePath( new TriplePath( new Triple( secondObject, RDF.rest.asNode(), thirdObject)));
+		epb.addTriplePath( new TriplePath( new Triple( thirdObject, RDF.first.asNode(), three)));
+		epb.addTriplePath( new TriplePath( new Triple( thirdObject, RDF.rest.asNode(), RDF.nil.asNode())));
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, foo, bar)));
+		
+		
+		WhereValidator visitor = new WhereValidator( epb );
+		query.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
 	}
 	
 	@Test

http://git-wip-us.apache.org/repos/asf/jena/blob/b1408fff/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 d53aa59..968c402 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,6 +23,9 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import org.apache.jena.arq.AbstractRegexpBasedTest;
+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.query.QueryExecution;
 import org.apache.jena.query.QueryExecutionFactory;
@@ -31,8 +34,10 @@ import org.apache.jena.query.ResultSet;
 import org.apache.jena.rdf.model.Model;
 import org.apache.jena.rdf.model.ModelFactory;
 import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.sparql.core.TriplePath;
 import org.apache.jena.sparql.core.Var;
 import org.apache.jena.sparql.lang.sparql_11.ParseException;
+import org.apache.jena.sparql.syntax.ElementPathBlock;
 import org.apache.jena.vocabulary.RDF;
 import org.apache.jena.vocabulary.XSD;
 import org.junit.Before;
@@ -128,14 +133,34 @@ public class SelectBuilderTest extends AbstractRegexpBasedTest {
 
 	@Test
 	public void testList() {
+		
 		builder.addVar("*").addWhere(builder.list("<one>", "?two", "'three'"), "<foo>", "<bar>");
-		String query = builder.buildString();
+		Query query = builder.build();
 
-		assertContainsRegex(PAREN_OPEN + SPACE + uri("one") + SPACE + var("two") + SPACE + quote("three") + SPACE + PAREN_CLOSE,
-		                    builder.buildString());
-
-		assertContainsRegex(PAREN_CLOSE + "." + SPACE + uri("foo") + SPACE  + uri("bar") + SPACE + CLOSE_CURLY,
-		                    builder.buildString());
+		
+		Node one = NodeFactory.createURI("one");
+		Node two = Var.alloc("two").asNode();
+		Node three = NodeFactory.createLiteral( "three");
+		Node foo = NodeFactory.createURI("foo");
+		Node bar = NodeFactory.createURI("bar");
+		
+		ElementPathBlock epb = new ElementPathBlock();
+		Node firstObject = NodeFactory.createBlankNode();		
+		Node secondObject = NodeFactory.createBlankNode();
+		Node thirdObject = NodeFactory.createBlankNode();
+		
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, RDF.first.asNode(), one)));
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, RDF.rest.asNode(), secondObject)));
+		epb.addTriplePath( new TriplePath( new Triple( secondObject, RDF.first.asNode(), two)));
+		epb.addTriplePath( new TriplePath( new Triple( secondObject, RDF.rest.asNode(), thirdObject)));
+		epb.addTriplePath( new TriplePath( new Triple( thirdObject, RDF.first.asNode(), three)));
+		epb.addTriplePath( new TriplePath( new Triple( thirdObject, RDF.rest.asNode(), RDF.nil.asNode())));
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, foo, bar)));
+		
+		
+		WhereValidator visitor = new WhereValidator( epb );
+		query.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
 	}
 
 	@Test

http://git-wip-us.apache.org/repos/asf/jena/blob/b1408fff/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/WhereValidator.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/WhereValidator.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/WhereValidator.java
new file mode 100644
index 0000000..a45e05a
--- /dev/null
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/WhereValidator.java
@@ -0,0 +1,205 @@
+/*
+ * 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.List;
+
+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.sparql.util.NodeIsomorphismMap;
+
+/**
+ * Class to validate that an element exists in another element structure.
+ *
+ */
+public class WhereValidator implements ElementVisitor {
+	
+	private Element target;
+	public boolean matching = false;
+	private NodeIsomorphismMap nim;
+	
+	public WhereValidator( Element target )
+	{
+		this.target = target;
+		this.nim = new NodeIsomorphismMap();
+	}
+	
+	private void checkMatching(Element el)
+	{
+		if (!matching)
+		{
+			matching = el.equalTo(target, nim);
+		}
+	}
+
+	@Override
+	public void visit(ElementTriplesBlock el) {
+		checkMatching( el );
+		return;
+	}
+
+	@Override
+	public void visit(ElementPathBlock el) {
+		checkMatching( el );
+		return;
+	}
+
+	@Override
+	public void visit(ElementFilter el) {
+		checkMatching( el );
+		return;
+	}
+
+	@Override
+	public void visit(ElementAssign el) {
+		checkMatching( el );
+		return;
+	}
+
+	@Override
+	public void visit(ElementBind el) {
+		checkMatching( el );
+		return;
+	}
+
+	@Override
+	public void visit(ElementData el) {
+		checkMatching( el );
+		return;
+	}
+
+	private void checkList( List<Element> lst )
+	{
+		for (Element e : lst)
+		{
+			e.visit( this );
+			if (matching)
+			{
+				return;
+			}
+		}
+	}
+	@Override
+	public void visit(ElementUnion el) {
+		checkMatching( el );
+		if (!matching)
+		{
+			checkList( el.getElements() );
+		}
+		return;
+	}
+
+	@Override
+	public void visit(ElementOptional el) {
+		checkMatching( el );
+		if (!matching)
+		{
+			el.getOptionalElement().visit(this);
+		}
+	}
+
+	@Override
+	public void visit(ElementGroup el) {
+		checkMatching( el );
+		if (!matching)
+		{
+			checkList( el.getElements() );
+		}
+	}
+
+	@Override
+	public void visit(ElementDataset el) {
+		checkMatching( el );
+		if (!matching)
+		{
+			el.getElement().visit( this );
+		}
+		
+	}
+
+	@Override
+	public void visit(ElementNamedGraph el) {
+		checkMatching( el );
+		if (!matching)
+		{
+			el.getElement().visit( this );
+		}
+	}
+
+	@Override
+	public void visit(ElementExists el) {
+		checkMatching( el );
+		if (!matching)
+		{
+			el.getElement().visit( this );
+		}
+	}
+
+	@Override
+	public void visit(ElementNotExists el) {
+		checkMatching( el );
+		if (!matching)
+		{
+			el.getElement().visit( this );
+		}
+	}
+
+	@Override
+	public void visit(ElementMinus el) {
+		checkMatching( el );
+		if (!matching)
+		{
+			el.getMinusElement().visit( this );
+		}
+	}
+
+	@Override
+	public void visit(ElementService el) {
+		checkMatching( el );
+		if (!matching)
+		{
+			el.getElement().visit( this );
+		}
+	}
+
+	@Override
+	public void visit(ElementSubQuery el) {
+		checkMatching( el );
+		if (!matching)
+		{
+			el.getQuery().getQueryPattern().visit(this);
+		}
+	}
+	
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/b1408fff/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
index 63d3fa1..3f778eb 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/WhereClauseTest.java
@@ -17,16 +17,15 @@
  */
 package org.apache.jena.arq.querybuilder.clauses;
 
-import java.util.List;
-
+import java.util.Arrays;
 import org.apache.jena.arq.querybuilder.AbstractQueryBuilder;
 import org.apache.jena.arq.querybuilder.SelectBuilder;
+import org.apache.jena.arq.querybuilder.WhereValidator;
 import org.apache.jena.graph.Node;
 import org.apache.jena.graph.NodeFactory;
 import org.apache.jena.graph.Triple;
 import org.apache.jena.graph.impl.LiteralLabelFactory;
 import org.apache.jena.query.Query;
-import org.apache.jena.query.QueryFactory;
 import org.apache.jena.shared.PrefixMapping;
 import org.apache.jena.shared.impl.PrefixMappingImpl;
 import org.apache.jena.sparql.core.TriplePath;
@@ -35,12 +34,14 @@ import org.apache.jena.sparql.expr.E_Random;
 import org.apache.jena.sparql.lang.sparql_11.ParseException;
 import org.apache.jena.sparql.path.Path;
 import org.apache.jena.sparql.path.PathParser;
-import org.apache.jena.sparql.syntax.Element;
-import org.apache.jena.sparql.syntax.ElementGroup;
+import org.apache.jena.sparql.syntax.ElementBind;
+import org.apache.jena.sparql.syntax.ElementOptional;
+import org.apache.jena.sparql.syntax.ElementPathBlock;
+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.vocabulary.RDF;
 import org.junit.After;
-import org.junit.Assert;
-
 import static org.junit.Assert.*;
 
 import org.xenei.junit.contract.Contract;
@@ -172,14 +173,22 @@ public class WhereClauseTest<T extends WhereClause<?>> extends
 		SelectBuilder pattern = new SelectBuilder();
 		pattern.addWhere( new Triple( s, q,  n123 ) );
 		pattern.addWhere( new Triple( s, v, x));
-		pattern.addFilter( "?x>56");
+
 		
 		WhereClause<?> whereClause = getProducer().newInstance();
 		AbstractQueryBuilder<?> builder = whereClause.addOptional( pattern );
+
+		ElementPathBlock epb = new ElementPathBlock();
+		ElementOptional optional = new ElementOptional(epb);
+		TriplePath tp = new TriplePath( new Triple(s, q, n123));
+		epb.addTriplePath( tp );
+		 tp = new TriplePath( new Triple(s, v, x));
+		epb.addTriplePath( tp );
 		
-		Query expected = QueryFactory.create( "SELECT * WHERE { OPTIONAL { ?s <urn:q> '123'^^<http://www.w3.org/2001/XMLSchema#int> . ?s <urn:v> ?x . FILTER(?x>56) }}");
+		WhereValidator visitor = new WhereValidator( optional );
+		builder.build().getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
 		
-		Assert.assertEquals( expected.getQueryPattern(), builder.build().getQueryPattern());	
 	}
 
 	@ContractTest
@@ -195,16 +204,24 @@ public class WhereClauseTest<T extends WhereClause<?>> extends
 	@ContractTest
 	public void testAddSubQuery() {
 		SelectBuilder sb = new SelectBuilder();
-		sb.addPrefix("pfx", "urn:uri").addVar("?x")
+		sb.addPrefix("pfx", "urn:uri:").addVar("?x")
 				.addWhere("pfx:one", "pfx:two", "pfx:three");
 		WhereClause<?> whereClause = getProducer().newInstance();
 		AbstractQueryBuilder<?> builder = whereClause.addSubQuery(sb);
-
-		assertContainsRegex(PREFIX + "pfx:" + SPACE + uri("urn:uri") + SPACE
-				+ ".*" + WHERE + OPEN_CURLY + OPEN_CURLY + SELECT + var("x")
-				+ SPACE + WHERE + OPEN_CURLY + "pfx:one" + SPACE + "pfx:two"
-				+ SPACE + "pfx:three" + OPT_SPACE + CLOSE_CURLY,
-				builder.buildString());
+		Query query = builder.build();
+
+		Query q2 = new Query();
+		q2.setQuerySelectType();
+		q2.addProjectVars( Arrays.asList( Var.alloc( "x")));
+		ElementPathBlock epb = new ElementPathBlock();
+		q2.setQueryPattern(epb);
+		epb.addTriplePath( new TriplePath( new Triple( NodeFactory.createURI( "urn:uri:one"),
+				NodeFactory.createURI( "urn:uri:two"),NodeFactory.createURI( "urn:uri:three"))));
+		ElementSubQuery esq = new ElementSubQuery( q2 );
+		
+		WhereValidator visitor = new WhereValidator( esq );
+		query.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
 
 	}
 
@@ -315,19 +332,50 @@ public class WhereClauseTest<T extends WhereClause<?>> extends
 	@ContractTest
 	public void testSetVarsInUnion() {
 		Var v = Var.alloc("v");
-		SelectBuilder sb = new SelectBuilder();
-		sb.addPrefix("pfx", "uri").addWhere("<one>", "<two>", v);
+		SelectBuilder sb1 = new SelectBuilder()
+		.addPrefix("pfx", "uri").addWhere("<one>", "<two>", v);
 		WhereClause<?> whereClause = getProducer().newInstance();
-		AbstractQueryBuilder<?> builder = whereClause.addUnion(sb);
+		whereClause.addUnion(sb1);		
+		SelectBuilder sb2 = new SelectBuilder().addWhere("<uno>", "<dos>", "<tres>");
+		AbstractQueryBuilder<?> builder = whereClause.addUnion(sb2);
+		Query query = builder.build();
 		
-		assertContainsRegex(WHERE + OPEN_CURLY + UNION + OPEN_CURLY
-				+ uri("one") + SPACE + uri("two") + SPACE + var("v") 
-				+ CLOSE_CURLY, builder.buildString());
+		Node one = NodeFactory.createURI("one");
+		Node two = NodeFactory.createURI("two");
+		Node three = NodeFactory.createURI("three");
+		Node uno = NodeFactory.createURI("uno");
+		Node dos = NodeFactory.createURI("dos");
+		Node tres = NodeFactory.createURI("tres");
+		
+		ElementUnion union = new ElementUnion();
+		ElementPathBlock epb = new ElementPathBlock();
+		Triple t = new Triple( one, two, v.asNode());
+		epb.addTriple(t);
+		union.addElement(epb);
+		ElementPathBlock epb2 = new ElementPathBlock();
+		t = new Triple( uno, dos, tres);
+		epb2.addTriple(t);
+		union.addElement(epb2);
+		WhereValidator visitor = new WhereValidator( union );
+		query.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
 
 		builder.setVar(v, NodeFactory.createURI("three"));
-		assertContainsRegex(WHERE + OPEN_CURLY + UNION + OPEN_CURLY
-				+ uri("one") + SPACE + uri("two") + SPACE + uri("three")
-				+ SPACE + CLOSE_CURLY, builder.buildString());
+		query = builder.build();
+		
+		union = new ElementUnion();
+		 epb = new ElementPathBlock();
+		 t = new Triple( one, two, three);
+		epb.addTriple(t);
+		union.addElement(epb);
+		 epb2 = new ElementPathBlock();
+		t = new Triple( uno, dos, tres);
+		epb2.addTriple(t);
+		union.addElement(epb2);
+		 visitor = new WhereValidator( union );
+			query.getQueryPattern().visit( visitor );
+			assertTrue( visitor.matching );
+
 	}
 
 	@ContractTest
@@ -335,19 +383,21 @@ public class WhereClauseTest<T extends WhereClause<?>> extends
 		Var v = Var.alloc("foo");
 		WhereClause<?> whereClause = getProducer().newInstance();
 		AbstractQueryBuilder<?> builder = whereClause.addBind("rand()", v);
+		Query query = builder.build();
+		
+		ElementBind bind = new ElementBind( v, new E_Random());
+		WhereValidator visitor = new WhereValidator( bind );
+		query.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
+		
+		Node three = NodeFactory.createURI("three");
+		builder.setVar(v, three );
+		query = builder.build();
+		
+		visitor = new WhereValidator( new ElementTriplesBlock() );
+		query.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
 
-		assertContainsRegex(
-				OPEN_CURLY + BIND + OPEN_PAREN + "rand\\(\\)" + SPACE + "AS"
-						+ SPACE + var("foo") + CLOSE_PAREN + CLOSE_CURLY,
-				builder.buildString());
-		builder.setVar(v, NodeFactory.createURI("three"));
-		Query q = builder.build();
-		ElementGroup eg = (ElementGroup) q.getQueryPattern();
-		List<Element> lst = eg.getElements();
-		assertEquals( "Should only be one element",  1, lst.size());
-		assertTrue( "Should have an ElementTriplesBlock", lst.get(0) instanceof ElementTriplesBlock );
-		ElementTriplesBlock etb = (ElementTriplesBlock)lst.get(0);
-		assertTrue( "ElementGroup should be empty", etb.isEmpty() );
 	}
 
 	@ContractTest
@@ -356,20 +406,21 @@ public class WhereClauseTest<T extends WhereClause<?>> extends
 		WhereClause<?> whereClause = getProducer().newInstance();
 		AbstractQueryBuilder<?> builder = whereClause
 				.addBind(new E_Random(), v);
+		Query query = builder.build();
+		
 
-		assertContainsRegex(
-				OPEN_CURLY + BIND + OPEN_PAREN + "rand\\(\\)" + SPACE + "AS"
-						+ SPACE + var("foo") + CLOSE_PAREN + CLOSE_CURLY,
-				builder.buildString());
+		WhereValidator visitor = new WhereValidator( new ElementBind( Var.alloc("foo"), new E_Random() ) );
+		query.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
+		
 		
 		builder.setVar(v, NodeFactory.createURI("three"));
-		Query q = builder.build();
-		ElementGroup eg = (ElementGroup) q.getQueryPattern();
-		List<Element> lst = eg.getElements();
-		assertEquals( "Should only be one element",  1, lst.size());
-		assertTrue( "Should have an ElementTriplesBlock", lst.get(0) instanceof ElementTriplesBlock );
-		ElementTriplesBlock etb = (ElementTriplesBlock)lst.get(0);
-		assertTrue( "ElementGroup should be empty", etb.isEmpty() );
+		query = builder.build();
+		
+		visitor = new WhereValidator( new ElementTriplesBlock() );
+		query.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
+		
 	}
 	
 	@ContractTest
@@ -378,11 +429,32 @@ public class WhereClauseTest<T extends WhereClause<?>> extends
 		AbstractQueryBuilder<?> builder = whereClause.addWhere(whereClause.list( "<one>", "?two", "'three'"),
 		                                                       "<foo>", "<bar>");
 	
-		assertContainsRegex(PAREN_OPEN + SPACE + uri("one") + SPACE + var("two") + SPACE + quote("three") + SPACE + PAREN_CLOSE,
-		                    builder.buildString());
+		Query query = builder.build();
 
-        assertContainsRegex(PAREN_CLOSE + "." + SPACE + uri("foo") + SPACE  + uri("bar") + SPACE + CLOSE_CURLY,
-                            builder.buildString());
+		Node one = NodeFactory.createURI("one");
+		Node two = Var.alloc("two").asNode();
+		Node three = NodeFactory.createLiteral( "three");
+		Node foo = NodeFactory.createURI("foo");
+		Node bar = NodeFactory.createURI("bar");
+		
+		ElementPathBlock epb = new ElementPathBlock();
+		Node firstObject = NodeFactory.createBlankNode();		
+		Node secondObject = NodeFactory.createBlankNode();
+		Node thirdObject = NodeFactory.createBlankNode();
+		
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, RDF.first.asNode(), one)));
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, RDF.rest.asNode(), secondObject)));
+		epb.addTriplePath( new TriplePath( new Triple( secondObject, RDF.first.asNode(), two)));
+		epb.addTriplePath( new TriplePath( new Triple( secondObject, RDF.rest.asNode(), thirdObject)));
+		epb.addTriplePath( new TriplePath( new Triple( thirdObject, RDF.first.asNode(), three)));
+		epb.addTriplePath( new TriplePath( new Triple( thirdObject, RDF.rest.asNode(), RDF.nil.asNode())));
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, foo, bar)));
+		
+		
+		WhereValidator visitor = new WhereValidator( epb );
+		query.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
+		
 	}
 	
 	@ContractTest

http://git-wip-us.apache.org/repos/asf/jena/blob/b1408fff/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java
----------------------------------------------------------------------
diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java
index 584d3a3..ce0e9aa 100644
--- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java
+++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/handlers/WhereHandlerTest.java
@@ -19,17 +19,18 @@ package org.apache.jena.arq.querybuilder.handlers;
 
 import static org.junit.Assert.assertTrue;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.jena.arq.querybuilder.SelectBuilder;
+import org.apache.jena.arq.querybuilder.WhereValidator;
 import org.apache.jena.arq.querybuilder.handlers.WhereHandler;
 import org.apache.jena.graph.Node;
 import org.apache.jena.graph.NodeFactory;
 import org.apache.jena.graph.Triple;
 import org.apache.jena.graph.impl.LiteralLabelFactory;
 import org.apache.jena.query.Query;
-import org.apache.jena.query.QueryFactory;
 import org.apache.jena.rdf.model.ResourceFactory;
 import org.apache.jena.shared.PrefixMapping;
 import org.apache.jena.shared.impl.PrefixMappingImpl;
@@ -39,8 +40,11 @@ import org.apache.jena.sparql.expr.E_Random;
 import org.apache.jena.sparql.lang.sparql_11.ParseException;
 import org.apache.jena.sparql.path.Path;
 import org.apache.jena.sparql.path.PathParser;
+import org.apache.jena.sparql.syntax.ElementOptional;
+import org.apache.jena.sparql.syntax.ElementPathBlock;
+import org.apache.jena.sparql.syntax.ElementSubQuery;
+import org.apache.jena.sparql.syntax.ElementUnion;
 import org.apache.jena.vocabulary.RDF;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -62,7 +66,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 		handler2.addWhere(new TriplePath(new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
 				NodeFactory.createLiteral("three"))));
 		handler.addAll(handler2);
-
+		handler.build();
+		
 		assertContainsRegex(
 				WHERE + OPEN_CURLY + uri("one") + SPACE + uri("two") + SPACE + quote("three") + OPT_SPACE + CLOSE_CURLY,
 				query.toString());
@@ -76,7 +81,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 		handler2.addWhere(new TriplePath(new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
 				NodeFactory.createLiteral("three"))));
 		handler.addAll(handler2);
-
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + "ANY" + SPACE + "ANY" + SPACE + "ANY" + DOT + SPACE + uri("one")
 				+ SPACE + uri("two") + SPACE + quote("three") + OPT_SPACE + CLOSE_CURLY, query.toString());
 	}
@@ -85,6 +91,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	public void addWhereTriple() {
 		handler.addWhere(new TriplePath(new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
 				NodeFactory.createURI("three"))));
+		handler.build();
+		
 		assertContainsRegex(
 				WHERE + OPEN_CURLY + uri("one") + SPACE + uri("two") + SPACE + uri("three") + OPT_SPACE + CLOSE_CURLY,
 				query.toString());
@@ -95,6 +103,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 		handler.addWhere(
 				new TriplePath(new Triple(NodeFactory.createURI("one"), ResourceFactory.createResource("two").asNode(),
 						ResourceFactory.createLangLiteral("three", "en-US").asNode())));
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + uri("one") + SPACE + uri("two") + SPACE + quote("three") + "@en-US"
 				+ OPT_SPACE + CLOSE_CURLY, query.toString());
 	}
@@ -106,6 +116,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 		Path path = PathParser.parse("ts:two/ts:dos", pmap);
 		handler.addWhere(new TriplePath(NodeFactory.createURI("one"), path,
 				ResourceFactory.createLangLiteral("three", "en-US").asNode()));
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + uri("one") + SPACE + uri("urn:test:two") + "/" + uri("urn:test:dos")
 				+ SPACE + quote("three") + "@en-US" + OPT_SPACE + CLOSE_CURLY, query.toString());
 	}
@@ -113,6 +125,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	@Test
 	public void testAddWhereAnonymous() {
 		handler.addWhere(new TriplePath(new Triple(Node.ANY, RDF.first.asNode(), Node.ANY)));
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + "ANY" + SPACE
 				+ uri("http://www\\.w3\\.org/1999/02/22-rdf-syntax-ns#first") + SPACE + "ANY" + OPT_SPACE + CLOSE_CURLY,
 				query.toString());
@@ -122,6 +136,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	public void testAddOptionalStrings() {
 		handler.addOptional(new TriplePath(new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
 				NodeFactory.createURI("three"))));
+		handler.build();
 		assertContainsRegex(WHERE + OPEN_CURLY + "OPTIONAL" + SPACE + OPEN_CURLY + uri("one") + SPACE + uri("two")
 				+ SPACE + uri("three") + OPT_SPACE + CLOSE_CURLY + CLOSE_CURLY, query.toString());
 	}
@@ -129,6 +144,7 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	@Test
 	public void testAddOptionalAnonymous() {
 		handler.addOptional(new TriplePath(new Triple(Node.ANY, RDF.first.asNode(), Node.ANY)));
+		handler.build();
 		assertContainsRegex(WHERE + OPEN_CURLY + "OPTIONAL" + SPACE + OPEN_CURLY + "ANY" + SPACE
 				+ uri("http://www\\.w3\\.org/1999/02/22-rdf-syntax-ns#first") + SPACE + "ANY" + OPT_SPACE + CLOSE_CURLY
 				+ CLOSE_CURLY, query.toString());
@@ -146,14 +162,20 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 
 		pattern.addWhere(new TriplePath(new Triple(s, q, n123)));
 		pattern.addWhere(new TriplePath(new Triple(s, v, x)));
-		pattern.addFilter("?x>56");
 
 		handler.addOptional(pattern);
-
-		Query expected = QueryFactory.create(
-				"SELECT * WHERE { OPTIONAL { ?s <urn:q> '123'^^<http://www.w3.org/2001/XMLSchema#int> . ?s <urn:v> ?x . FILTER(?x>56) }}");
-
-		Assert.assertEquals(expected.getQueryPattern(), query.getQueryPattern());
+		handler.build();
+		
+		ElementPathBlock epb = new ElementPathBlock();
+		ElementOptional optional = new ElementOptional(epb);
+		TriplePath tp = new TriplePath( new Triple(s, q, n123));
+		epb.addTriplePath( tp );
+		 tp = new TriplePath( new Triple(s, v, x));
+		epb.addTriplePath( tp );
+		
+		WhereValidator visitor = new WhereValidator( optional );
+		handler.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
 
 	}
 
@@ -162,6 +184,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 		handler.addOptional(
 				new TriplePath(new Triple(NodeFactory.createURI("one"), ResourceFactory.createResource("two").asNode(),
 						ResourceFactory.createLangLiteral("three", "en-US").asNode())));
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + "OPTIONAL" + SPACE + OPEN_CURLY + uri("one") + SPACE + uri("two")
 				+ SPACE + quote("three") + "@en-US" + OPT_SPACE + CLOSE_CURLY + CLOSE_CURLY, query.toString());
 	}
@@ -174,6 +198,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 
 		handler.addOptional(new TriplePath(NodeFactory.createURI("one"), path,
 				ResourceFactory.createLangLiteral("three", "en-US").asNode()));
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + "OPTIONAL" + SPACE + OPEN_CURLY + uri("one") + SPACE
 				+ uri("urn:test:two") + "/" + uri("urn:test:dos") + SPACE + quote("three") + "@en-US" + OPT_SPACE
 				+ CLOSE_CURLY + CLOSE_CURLY, query.toString());
@@ -183,6 +209,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	public void testAddWhereStrings() {
 		handler.addWhere(new TriplePath(new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"),
 				NodeFactory.createURI("three"))));
+		handler.build();
+		
 		assertContainsRegex(
 				WHERE + OPEN_CURLY + uri("one") + SPACE + uri("two") + SPACE + uri("three") + OPT_SPACE + CLOSE_CURLY,
 				query.toString());
@@ -191,7 +219,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	@Test
 	public void testAddFilter() throws ParseException {
 		handler.addFilter("?one < 10");
-
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + "FILTER" + OPT_SPACE + OPEN_PAREN + var("one") + OPT_SPACE + LT
 				+ OPT_SPACE + "10" + CLOSE_PAREN + CLOSE_CURLY, query.toString());
 	}
@@ -200,7 +229,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	public void testAddFilterWithNamespace() throws ParseException {
 		query.setPrefix("afn", "http://jena.apache.org/ARQ/function#");
 		handler.addFilter("afn:namespace(?one) = 'foo'");
-
+		handler.build();
+		
 		assertContainsRegex(
 				WHERE + OPEN_CURLY + "FILTER" + OPT_SPACE + OPEN_PAREN + "afn:namespace" + OPEN_PAREN + var("one")
 						+ CLOSE_PAREN + OPT_SPACE + EQ + OPT_SPACE + QUOTE + "foo" + QUOTE + CLOSE_PAREN + CLOSE_CURLY,
@@ -210,7 +240,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	@Test
 	public void testAddFilterVarOnly() throws ParseException {
 		handler.addFilter("?one");
-
+		handler.build();
+		
 		assertContainsRegex(
 				WHERE + OPEN_CURLY + "FILTER" + OPT_SPACE + OPEN_PAREN + var("one") + CLOSE_PAREN + CLOSE_CURLY,
 				query.toString());
@@ -221,6 +252,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 		SelectBuilder sb = new SelectBuilder();
 		sb.addPrefix("pfx", "uri").addVar("?x").addWhere("<one>", "<two>", "three");
 		handler.addSubQuery(sb);
+		handler.build();
+		
 		assertContainsRegex(SELECT + var("x") + SPACE + WHERE + OPEN_CURLY + uri("one") + SPACE + uri("two") + SPACE
 				+ quote("three") + CLOSE_CURLY, query.toString());
 	}
@@ -230,6 +263,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 		SelectBuilder sb = new SelectBuilder();
 		sb.addPrefix("pfx", "uri").addVar("count(*)", "?x").addWhere("<one>", "<two>", "three");
 		handler.addSubQuery(sb);
+		handler.build();
+		
 		assertContainsRegex(SELECT + OPEN_PAREN + "count" + OPEN_PAREN + "\\*" + CLOSE_PAREN + SPACE + "AS" + SPACE
 				+ var("x") + CLOSE_PAREN + SPACE + WHERE + OPEN_CURLY + uri("one") + SPACE + uri("two") + SPACE
 				+ quote("three") + CLOSE_CURLY, query.toString());
@@ -240,30 +275,69 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 		SelectBuilder sb = new SelectBuilder();
 		sb.addPrefix("pfx", "uri").addWhere("<one>", "<two>", "three");
 		handler.addSubQuery(sb);
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + uri("one") + SPACE + uri("two") + SPACE + quote("three") + CLOSE_CURLY,
 				query.toString());
 	}
 
 	@Test
 	public void testAddUnion() {
-		SelectBuilder sb = new SelectBuilder();
-		sb.addWhere(
-				new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three")));
+		Triple t1 = new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three"));
+		Triple t2 = new Triple(NodeFactory.createURI("uno"), NodeFactory.createURI("dos"), NodeFactory.createURI("tres"));
+				
+		SelectBuilder sb1 = new SelectBuilder()
+		.addWhere( t1 );
+		
+		SelectBuilder sb2 = new SelectBuilder()
+				.addWhere( t2 );
+				
+		handler.addUnion(sb1);
+		handler.addUnion(sb2);
+		handler.build();
+		
 
-		handler.addUnion(sb);
-		assertContainsRegex(WHERE + OPEN_CURLY + UNION + OPEN_CURLY + uri("one") + SPACE + uri("two") + SPACE
-				+ uri("three") + OPT_SPACE + CLOSE_CURLY, query.toString());
+		ElementUnion union = new ElementUnion();
+		ElementPathBlock epb1 = new ElementPathBlock();
+		epb1.addTriple(t1);
+		union.addElement( epb1 );
+		
+		ElementPathBlock epb2 = new ElementPathBlock();
+		epb2.addTriple(t2);
+		union.addElement( epb2 );
+		
+		WhereValidator visitor = new WhereValidator( union );
+		handler.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
+		
 	}
 
 	@Test
+	public void testAddUnionOfOne() {
+		Triple t1 = new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three"));
+		SelectBuilder sb = new SelectBuilder().addWhere(t1);
+		handler.addUnion(sb);
+		handler.build();
+		
+		
+		ElementPathBlock epb1 = new ElementPathBlock();
+		epb1.addTriple(t1);
+		
+		WhereValidator visitor = new WhereValidator( epb1 );
+		handler.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
+	}
+	
+	@Test
 	public void testAddUnionToExisting() {
 		handler.addWhere(new TriplePath(
 				new Triple(NodeFactory.createURI("s"), NodeFactory.createURI("p"), NodeFactory.createURI("o"))));
 		SelectBuilder sb = new SelectBuilder();
 		sb.addWhere(
 				new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three")));
-
 		handler.addUnion(sb);
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + OPEN_CURLY + uri("s") + SPACE + uri("p") + SPACE + uri("o")
 				+ CLOSE_CURLY + OPT_SPACE + UNION + OPEN_CURLY + uri("one") + SPACE + uri("two") + SPACE + uri("three")
 				+ OPT_SPACE + CLOSE_CURLY + CLOSE_CURLY, query.toString());
@@ -271,18 +345,41 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 
 	@Test
 	public void testAddUnionWithVar() {
-		SelectBuilder sb = new SelectBuilder().addVar("x").addWhere(
-				new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three")));
-
+		Triple t1 = new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three"));
+		Triple t2 = new Triple(NodeFactory.createURI("uno"), NodeFactory.createURI("dos"), NodeFactory.createURI("tres"));
+		
+		SelectBuilder sb = new SelectBuilder().addVar("x").addWhere( t1 );
 		handler.addUnion(sb);
-		assertContainsRegex(WHERE + OPEN_CURLY + UNION + OPEN_CURLY + SELECT + var("x") + SPACE + WHERE + OPEN_CURLY
-				+ uri("one") + SPACE + uri("two") + SPACE + uri("three") + OPT_SPACE + CLOSE_CURLY, query.toString());
+			
+		SelectBuilder sb2 = new SelectBuilder().addWhere( t2 );
+		handler.addUnion( sb2 );
+		handler.build();
+		
+		ElementUnion union = new ElementUnion();
+		Query q = new Query();
+		q.setQuerySelectType();
+		ElementPathBlock epb1 = new ElementPathBlock();
+		epb1.addTriple(t1);
+		q.setQueryPattern(epb1);
+		q.addProjectVars( Arrays.asList(Var.alloc( "x" )));
+		ElementSubQuery sq = new ElementSubQuery(q);
+		union.addElement( sq );
+		ElementPathBlock epb2 = new ElementPathBlock();
+		epb2.addTriple(t2);
+		union.addElement( epb2 );
+		
+		WhereValidator visitor = new WhereValidator( union );
+		handler.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
+				
 	}
 
 	@Test
 	public void testAddUnionToExistingWithVar() {
 		handler.addWhere(new TriplePath(
 				new Triple(NodeFactory.createURI("s"), NodeFactory.createURI("p"), NodeFactory.createURI("o"))));
+		handler.build();
+		
 		SelectBuilder sb = new SelectBuilder().addVar("x").addWhere(
 				new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"), NodeFactory.createURI("three")));
 
@@ -300,6 +397,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 				NodeFactory.createURI("three"))));
 
 		handler.addGraph(NodeFactory.createURI("graph"), handler2);
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + "GRAPH" + SPACE + uri("graph") + SPACE + OPEN_CURLY + uri("one")
 				+ SPACE + uri("two") + SPACE + uri("three") + OPT_SPACE + CLOSE_CURLY + CLOSE_CURLY, query.toString());
 
@@ -309,6 +408,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	public void testSetVarsInTriple() {
 		Var v = Var.alloc("v");
 		handler.addWhere(new TriplePath(new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"), v)));
+		handler.build();
+		
 		assertContainsRegex(
 				WHERE + OPEN_CURLY + uri("one") + SPACE + uri("two") + SPACE + var("v") + OPT_SPACE + CLOSE_CURLY,
 				query.toString());
@@ -329,6 +430,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 
 		values.put(Var.alloc("v"), NodeFactory.createLiteral(LiteralLabelFactory.createTypedLiteral(10)));
 		handler.setVars(values);
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + "FILTER" + OPT_SPACE + OPEN_PAREN + var("one") + OPT_SPACE + LT
 				+ OPT_SPACE + quote("10") + "\\^\\^" + uri("http://www.w3.org/2001/XMLSchema#int") + CLOSE_PAREN
 				+ CLOSE_CURLY, query.toString());
@@ -339,11 +442,16 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	public void testSetVarsInOptional() {
 		Var v = Var.alloc("v");
 		handler.addOptional(new TriplePath(new Triple(NodeFactory.createURI("one"), NodeFactory.createURI("two"), v)));
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + "OPTIONAL" + SPACE + OPEN_CURLY + uri("one") + SPACE + uri("two")
 				+ SPACE + var("v") + OPT_SPACE + CLOSE_CURLY + CLOSE_CURLY, query.toString());
+
 		Map<Var, Node> values = new HashMap<>();
 		values.put(v, NodeFactory.createURI("three"));
 		handler.setVars(values);
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + "OPTIONAL" + SPACE + OPEN_CURLY + uri("one") + SPACE + uri("two")
 				+ SPACE + uri("three") + OPT_SPACE + CLOSE_CURLY + CLOSE_CURLY, query.toString());
 	}
@@ -354,11 +462,16 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 		SelectBuilder sb = new SelectBuilder();
 		sb.addPrefix("pfx", "uri").addWhere("<one>", "<two>", v);
 		handler.addSubQuery(sb);
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + uri("one") + ".+" + uri("two") + ".+" + var("v") + ".+" + CLOSE_CURLY,
 				query.toString());
+		
 		Map<Var, Node> values = new HashMap<>();
 		values.put(v, NodeFactory.createURI("three"));
 		handler.setVars(values);
+		handler.build();
+		
 		assertContainsRegex(
 				WHERE + OPEN_CURLY + uri("one") + ".+" + uri("two") + ".+" + uri("three") + ".+" + CLOSE_CURLY,
 				query.toString());
@@ -370,20 +483,56 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 		SelectBuilder sb = new SelectBuilder();
 		sb.addPrefix("pfx", "uri").addWhere("<one>", "<two>", v);
 		handler.addUnion(sb);
-		assertContainsRegex(WHERE + OPEN_CURLY + UNION + OPEN_CURLY + uri("one") + ".+" + uri("two") + ".+" + var("v")
-				+ ".+" + CLOSE_CURLY, query.toString());
+		SelectBuilder sb2 = new SelectBuilder().addWhere( "<uno>", "<dos>", "<tres>");
+		handler.addUnion(sb2);
+		handler.build();
+		
+		Node one = NodeFactory.createURI("one");
+		Node two = NodeFactory.createURI("two");
+		Node three = NodeFactory.createURI("three");
+		Node uno = NodeFactory.createURI("uno");
+		Node dos = NodeFactory.createURI("dos");
+		Node tres = NodeFactory.createURI("tres");
+		
+		ElementUnion union = new ElementUnion();
+		ElementPathBlock epb = new ElementPathBlock();
+		Triple t = new Triple( one, two, v.asNode());
+		epb.addTriple(t);
+		union.addElement(epb);
+		ElementPathBlock epb2 = new ElementPathBlock();
+		t = new Triple( uno, dos, tres);
+		epb2.addTriple(t);
+		union.addElement(epb2);
+		WhereValidator visitor = new WhereValidator( union );
+		handler.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
+		
 		Map<Var, Node> values = new HashMap<>();
-		values.put(v, NodeFactory.createURI("three"));
+		values.put(v, three);
 		handler.setVars(values);
-		assertContainsRegex(WHERE + OPEN_CURLY + UNION + OPEN_CURLY + uri("one") + ".+" + uri("two") + ".+"
-				+ uri("three") + ".+" + CLOSE_CURLY, query.toString());
+		handler.build();
+		
+		 union = new ElementUnion();
+		 epb = new ElementPathBlock();
+		 t = new Triple( one, two, three);
+		epb.addTriple(t);
+		union.addElement(epb);
+		 epb2 = new ElementPathBlock();
+		t = new Triple( uno, dos, tres);
+		epb2.addTriple(t);
+		union.addElement(epb2);
+		 visitor = new WhereValidator( union );
+			handler.getQueryPattern().visit( visitor );
+			assertTrue( visitor.matching );
+			
 	}
 
 	@Test
 	public void testBindStringVar() throws ParseException {
 		Var v = Var.alloc("foo");
 		handler.addBind("rand()", v);
-
+		handler.build();
+		
 		assertContainsRegex(OPEN_CURLY + BIND + OPEN_PAREN + "rand\\(\\)" + SPACE + "AS" + SPACE + var("foo")
 				+ CLOSE_PAREN + CLOSE_CURLY, query.toString());
 	}
@@ -392,28 +541,36 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	public void testBindExprVar() {
 		Var v = Var.alloc("foo");
 		handler.addBind(new E_Random(), v);
-
+		handler.build();
+		
 		assertContainsRegex(OPEN_CURLY + BIND + OPEN_PAREN + "rand\\(\\)" + SPACE + "AS" + SPACE + var("foo")
 				+ CLOSE_PAREN + CLOSE_CURLY, query.toString());
 	}
 
 	@Test
 	public void testList() {
-		Node n = handler.list("<one>", "?var", "'three'");
-		
-		// HAndler.addList, unlike adding a WhereClause, ends up with ElementPathBlock and TriplePath.
-        assertContainsRegex(WHERE + OPEN_CURLY + "_:b0" + SPACE
-               + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first") + SPACE + uri("one") + SEMI + SPACE
-               + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest") + SPACE + "_:b1" + DOT + SPACE + "_:b1" + SPACE
-               + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first") + SPACE + var("var") + SEMI + SPACE
-               + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest") + SPACE + "_:b2" + DOT + SPACE + "_:b2" + SPACE
-               + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first") + SPACE + quote("three") + SEMI + SPACE
-               + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest") + SPACE
-               + uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil") + CLOSE_CURLY, query.toString());
-
-        // If it were a basic graph pattern... 
-//		assertContainsRegex(WHERE + OPEN_CURLY + "("+SPACE+uri("one")+SPACE+var("var")+SPACE+quote("three")+")"+CLOSE_CURLY,
-//		                    query.toString());
+		Node n = handler.list("<one>", "?var", "'three'");        
+		
+		Node one = NodeFactory.createURI("one");
+		Node two = Var.alloc("var").asNode();
+		Node three = NodeFactory.createLiteral( "three");
+		
+		ElementPathBlock epb = new ElementPathBlock();
+		Node firstObject = NodeFactory.createBlankNode();		
+		Node secondObject = NodeFactory.createBlankNode();
+		Node thirdObject = NodeFactory.createBlankNode();
+		
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, RDF.first.asNode(), one)));
+		epb.addTriplePath( new TriplePath( new Triple( firstObject, RDF.rest.asNode(), secondObject)));
+		epb.addTriplePath( new TriplePath( new Triple( secondObject, RDF.first.asNode(), two)));
+		epb.addTriplePath( new TriplePath( new Triple( secondObject, RDF.rest.asNode(), thirdObject)));
+		epb.addTriplePath( new TriplePath( new Triple( thirdObject, RDF.first.asNode(), three)));
+		epb.addTriplePath( new TriplePath( new Triple( thirdObject, RDF.rest.asNode(), RDF.nil.asNode())));
+		
+		
+		WhereValidator visitor = new WhereValidator( epb );
+		query.getQueryPattern().visit( visitor );
+		assertTrue( visitor.matching );
 		                    
 		assertTrue(n.isBlank());
 	}
@@ -422,7 +579,8 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 	public void testListInTriple() {
 		handler.addWhere(new TriplePath(new Triple(handler.list("<one>", "?var", "'three'"),
 				ResourceFactory.createResource("foo").asNode(), ResourceFactory.createResource("bar").asNode())));
-
+		handler.build();
+		
 		assertContainsRegex(WHERE + OPEN_CURLY + PAREN_OPEN+SPACE+uri("one")+SPACE+var("var")+SPACE+quote("three")+SPACE+PAREN_CLOSE ,
 		                    query.toString());
 
@@ -433,8 +591,9 @@ public class WhereHandlerTest extends AbstractHandlerTest {
 		SelectBuilder sb = new SelectBuilder();
 		sb.addPrefix("pfx", "uri").addWhere("<one>", "<two>", "three");
 		handler.addMinus(sb);
+		handler.build();
+		
 		assertContainsRegex(MINUS + OPEN_CURLY + uri("one") + SPACE + uri("two") + SPACE + quote("three") + CLOSE_CURLY,
 				query.toString());		
 	}
-	
 }


[2/2] jena git commit: fix for JENA-1365

Posted by cl...@apache.org.
fix for JENA-1365

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

Branch: refs/heads/master
Commit: 9093863bff4b436adeb9e502c3b3437af17f7e07
Parents: b1408ff
Author: Claude Warren <cl...@apache.org>
Authored: Sat Jun 24 09:40:51 2017 +0100
Committer: Claude Warren <cl...@apache.org>
Committed: Sat Jun 24 09:40:51 2017 +0100

----------------------------------------------------------------------

----------------------------------------------------------------------