Repository: jena Updated Branches: refs/heads/master e5ed9b9c4 -> 08d231d8c
fixes for JENA-1455 and JENA-1456 also minor fixes for JENA-1368 Project: http://git-wip-us.apache.org/repos/asf/jena/repo Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/5e6c047e Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/5e6c047e Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/5e6c047e Branch: refs/heads/master Commit: 5e6c047e2fb83609191c2b7c15fa9103fb7cc08b Parents: d516f35 Author: Claude Warren <[email protected]> Authored: Tue Dec 26 23:17:43 2017 +0000 Committer: Claude Warren <[email protected]> Committed: Tue Dec 26 23:19:58 2017 +0000 ---------------------------------------------------------------------- .../arq/querybuilder/AbstractQueryBuilder.java | 185 ++++---- .../jena/arq/querybuilder/UpdateBuilder.java | 2 +- .../jena/arq/querybuilder/WhereBuilder.java | 247 +++++++++++ .../arq/querybuilder/handlers/WhereHandler.java | 212 +--------- .../rewriters/AbstractRewriter.java | 1 + .../rewriters/BuildElementVisitor.java | 234 +++++++++++ .../updatebuilder/QuadIteratorBuilder.java | 52 +-- .../updatebuilder/SingleQuadHolder.java | 31 +- .../updatebuilder/WhereProcessor.java | 28 +- .../querybuilder/AbstractQueryBuilderTest.java | 5 + .../arq/querybuilder/UpdateBuilderTest.java | 84 +++- .../querybuilder/WhereBuilderContractTest.java | 53 +++ .../clauses/SolutionModifierTest.java | 151 ++++++- .../querybuilder/clauses/WhereClauseTest.java | 418 ++++++++++++++++++- 14 files changed, 1344 insertions(+), 359 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/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 6ca1052..8e3056e 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 @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; + import org.apache.jena.arq.querybuilder.clauses.PrologClause; import org.apache.jena.arq.querybuilder.clauses.ValuesClause; import org.apache.jena.arq.querybuilder.handlers.HandlerBlock; @@ -61,12 +62,12 @@ import org.apache.jena.sparql.util.NodeFactoryExtra ; * The derived class type. Used for return types. */ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> - implements Cloneable, PrologClause<T>, ValuesClause<T> { +implements Cloneable, PrologClause<T>, ValuesClause<T> { // the query this builder is building protected Query query; // a map of vars to nodes for replacement during build. - private Map<Var, Node> values; + private final Map<Var, Node> values; /** * Make a Node from an object. @@ -89,12 +90,12 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> public Node makeNode(Object o) { return makeNode( o, query.getPrefixMapping() ); } - + private Object makeNodeOrPath(Object o) { return makeNodeOrPath(o, query.getPrefixMapping() ); } - + private Object makeNodeOrPath(Object o, PrefixMapping pMapping) { if (o == null) { @@ -113,18 +114,18 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> } if (o instanceof String) { try { - Path p = PathParser.parse((String) o, pMapping); + final Path p = PathParser.parse((String) o, pMapping); if (p instanceof P_Link) { return ((P_Link)p).getNode(); } return p; } - catch (QueryParseException e) + catch (final QueryParseException e) { // try to parse vars return makeNode( o, pMapping ); } - catch (Exception e) + catch (final Exception e) { // expected in some cases -- do nothing } @@ -132,11 +133,11 @@ 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. * @@ -161,7 +162,7 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> * @return a TriplePath */ public TriplePath makeTriplePath(Object s, Object p, Object o) { - Object po = makeNodeOrPath( p ); + final Object po = makeNodeOrPath( p ); if (po instanceof Path) { return new TriplePath(makeNode(s), (Path)po, makeNode(o)); @@ -169,10 +170,10 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> { return new TriplePath( new Triple( makeNode(s), (Node)po, makeNode(o))); } - + } - + /** * A convenience method to make an expression from a string. Evaluates the * expression with respect to the current query. @@ -185,7 +186,7 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> { return ExprUtils.parse(query, expression, true); } - + /** * A convenience method to quote a string. * @param q the string to quote. @@ -198,16 +199,30 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> * @return the quoted string. */ public static String quote(String q) { - int qt = q.indexOf('"'); - int sqt = q.indexOf("'"); - + final int qt = q.indexOf('"'); + final int sqt = q.indexOf("'"); + if (sqt == -1 || qt<sqt) { return String.format( "'%s'", q); } return String.format( "\"%s\"", q); } - + + /** + * Verify that any Node_Variable nodes are returned as Var nodes. + * @param n the node to check + * @return the node n or a new Var if n is an instance of Node_Variable + */ + public static Node checkVar(Node n ) + { + if (n.isVariable()) + { + return Var.alloc( n ); + } + return n; + } + /** * Make a node from an object while using the associated prefix mapping. * <ul> @@ -228,17 +243,17 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> return Node.ANY; } if (o instanceof FrontsNode) { - return ((FrontsNode) o).asNode(); + return checkVar(((FrontsNode) o).asNode()); } if (o instanceof Node) { - return (Node) o; + return checkVar( (Node) o ); } if (o instanceof String) { try { - return NodeFactoryExtra.parseNode((String) o, PrefixMapFactory - .createForInput(pMapping)); - } catch (RiotException e) { + return checkVar(NodeFactoryExtra.parseNode((String) o, PrefixMapFactory + .createForInput(pMapping))); + } catch (final RiotException e) { // expected in some cases -- do nothing } @@ -298,13 +313,13 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> query = new Query(); values = new HashMap<Var, Node>(); } - + /** * Get the HandlerBlock for this query builder. * @return The associated handler block. */ public abstract HandlerBlock getHandlerBlock(); - + @Override public final PrologHandler getPrologHandler() { return getHandlerBlock().getPrologHandler(); @@ -314,11 +329,12 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> public ValuesHandler getValuesHandler() { return getHandlerBlock().getValueHandler(); } - + public final WhereHandler getWhereHandler() { return getHandlerBlock().getWhereHandler(); } + @Override public final ExprFactory getExprFactory() { return getHandlerBlock().getPrologHandler().getExprFactory(); } @@ -400,19 +416,19 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> setBase(makeNode(base).getURI()); return (T) this; } - + // --- VALUES - + public static Collection<Node> makeValueNodes( Iterator<?> iter, PrefixMapping prefixMapping ) { if (iter == null || !iter.hasNext()) { return null; } - List<Node> values = new ArrayList<Node>(); + final List<Node> values = new ArrayList<Node>(); while (iter.hasNext()) { - Object o = iter.next(); + final Object o = iter.next(); // handle null as UNDEF if (o == null) { @@ -429,7 +445,7 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> { return makeValueNodes( iter, getPrologHandler().getPrefixes() ); } - + @SuppressWarnings("unchecked") @Override public T addValueVar(Object var) { @@ -439,13 +455,13 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> } if (var instanceof Collection<?>) { - Collection<?> column = (Collection<?>)var; + final Collection<?> column = (Collection<?>)var; if (column.size() == 0) { throw new IllegalArgumentException( "column must have at least one entry."); } - Iterator<?> iter = column.iterator(); - Var v = makeVar( iter.next() ); + final Iterator<?> iter = column.iterator(); + final Var v = makeVar( iter.next() ); getValuesHandler().addValueVar(v, makeValueNodes(iter)); } else { getValuesHandler().addValueVar(makeVar(var), null ); @@ -456,22 +472,22 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> @SuppressWarnings("unchecked") @Override public T addValueVar(Object var, Object... objects) { - + Collection<Node> values = null; if (objects != null) { values = makeValueNodes( Arrays.asList(objects).iterator()); } - + getValuesHandler().addValueVar(makeVar(var), values ); return (T) this; } - + @SuppressWarnings("unchecked") @Override public <K extends Collection<?>> T addValueVars(Map<?,K> dataTable) { - ValuesHandler hdlr = new ValuesHandler( null ); - for (Map.Entry<?, K> entry : dataTable.entrySet()) + final ValuesHandler hdlr = new ValuesHandler( null ); + for (final Map.Entry<?, K> entry : dataTable.entrySet()) { Collection<Node> values = null; if (entry.getValue() != null) @@ -483,7 +499,7 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> getValuesHandler().addAll( hdlr ); return (T) this; } - + @SuppressWarnings("unchecked") @Override public T addValueRow(Object... values) { @@ -497,7 +513,7 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> getValuesHandler().addValueRow( makeValueNodes( values.iterator())); return (T) this; } - + @Override public List<Var> getValuesVars() { return getValuesHandler().getValuesVars(); @@ -507,7 +523,7 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> public Map<Var,List<Node>> getValuesMap() { return getValuesHandler().getValuesMap(); } - + @SuppressWarnings("unchecked") @Override public T clearValues() { @@ -536,40 +552,43 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> * @return The query. */ public final Query build() { - Query q = new Query(); - + final Query q = new Query(); + // set the query type switch (query.getQueryType()) { - case Query.QueryTypeAsk: - q.setQueryAskType(); - break; - case Query.QueryTypeConstruct: - q.setQueryConstructType(); - break; - case Query.QueryTypeDescribe: - q.setQueryDescribeType(); - break; - case Query.QueryTypeSelect: - q.setQuerySelectType(); - break; - default: - throw new IllegalStateException( "Internal query is not a known type: "+q.getQueryType()); + case Query.QueryTypeAsk: + q.setQueryAskType(); + break; + case Query.QueryTypeConstruct: + q.setQueryConstructType(); + break; + case Query.QueryTypeDescribe: + q.setQueryDescribeType(); + break; + case Query.QueryTypeSelect: + q.setQuerySelectType(); + break; + case Query.QueryTypeUnknown: + // do nothing + break; + default: + throw new IllegalStateException( "Internal query is not a known type: "+q.getQueryType()); } - + // use the HandlerBlock implementation to copy the data. - HandlerBlock handlerBlock = new HandlerBlock(q); + final HandlerBlock handlerBlock = new HandlerBlock(q); handlerBlock.addAll( getHandlerBlock() ); - + // set the vars handlerBlock.setVars(values); - + // make sure we have a query pattern before we start building. if (q.getQueryPattern() == null) { q.setQueryPattern( new ElementGroup() ); } - + handlerBlock.build(); return q; @@ -586,27 +605,27 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> * @return A clone of the q2 param. */ public static Query clone(Query q2) { - Query retval = new Query(); - + final Query retval = new Query(); + // set the query type - if (q2.isSelectType()) - { - retval.setQuerySelectType(); - } else if (q2.isAskType()) { - retval.setQueryAskType(); - } else if (q2.isDescribeType()) - { - retval.setQueryDescribeType(); - } else if (q2.isConstructType()) - { - retval.setQueryConstructType(); - } - - // use the handler block to clone the data - HandlerBlock hb = new HandlerBlock( retval ); - HandlerBlock hb2 = new HandlerBlock( q2 ); - hb.addAll(hb2); - + if (q2.isSelectType()) + { + retval.setQuerySelectType(); + } else if (q2.isAskType()) { + retval.setQueryAskType(); + } else if (q2.isDescribeType()) + { + retval.setQueryDescribeType(); + } else if (q2.isConstructType()) + { + retval.setQueryConstructType(); + } + + // use the handler block to clone the data + final HandlerBlock hb = new HandlerBlock( retval ); + final HandlerBlock hb2 = new HandlerBlock( q2 ); + hb.addAll(hb2); + return retval; } @@ -620,7 +639,7 @@ public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> * @return The new query with the specified vars replaced. */ public static Query rewrite(Query q2, Map<Var, Node> values) { - HandlerBlock hb = new HandlerBlock(q2); + final HandlerBlock hb = new HandlerBlock(q2); hb.setVars(values); return q2; } http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/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 index f6a6eb5..2fb8fc8 100644 --- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/UpdateBuilder.java +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/UpdateBuilder.java @@ -224,7 +224,7 @@ public class UpdateBuilder { } } - retval.setElement(whereProcessor.setVars(values)); + retval.setElement(whereProcessor.setVars(values).build()); return retval; http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/WhereBuilder.java ---------------------------------------------------------------------- diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/WhereBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/WhereBuilder.java new file mode 100644 index 0000000..7d77220 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/WhereBuilder.java @@ -0,0 +1,247 @@ +/* + * 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.Collection; +import java.util.List; +import java.util.Map; + +import org.apache.jena.arq.querybuilder.clauses.WhereClause; +import org.apache.jena.arq.querybuilder.handlers.HandlerBlock; +import org.apache.jena.arq.querybuilder.handlers.WhereHandler; +import org.apache.jena.graph.FrontsTriple; +import org.apache.jena.graph.Node; +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.expr.Expr; +import org.apache.jena.sparql.lang.sparql_11.ParseException; + +/** + * A simple implementation of WhereClause for use in building complex sub queries where + * a SelectBuilder or similar implementation is more than is needed. + * + */ +public class WhereBuilder extends AbstractQueryBuilder<WhereBuilder> implements WhereClause<WhereBuilder> +{ + private HandlerBlock block; + private WhereHandler handler; + + /** + * Constructor. + */ + public WhereBuilder() { + query = new Query(); + block = new HandlerBlock(query); + handler = block.getWhereHandler(); + } + + @Override + public WhereBuilder addWhere(Triple t) + { + return addWhere( new TriplePath( t )); + } + + @Override + public WhereBuilder addWhere(TriplePath t) + { + handler.addWhere(t); + return this; + } + + @Override + public WhereBuilder addWhere(FrontsTriple t) + { + return addWhere( t.asTriple() ); + } + + @Override + public WhereBuilder addWhere(Object s, Object p, Object o) + { + return addWhere( makeTriplePath( s, p, o )); + } + + @Override + public WhereBuilder addWhereValueVar(Object var) { + handler.addValueVar(getPrologHandler().getPrefixes(), var); + return this; + } + + @Override + public WhereBuilder addWhereValueVar(Object var, Object... values) + { + getWhereHandler().addValueVar(getPrologHandler().getPrefixes(), var, values); + return this; + } + + + @Override + public <K extends Collection<?>> WhereBuilder addWhereValueVars(Map<?,K> dataTable) + { + getWhereHandler().addValueVars(getPrologHandler().getPrefixes(), dataTable); + return this; + } + + @Override + public WhereBuilder addWhereValueRow(Object... values) + { + getWhereHandler().addValueRow(getPrologHandler().getPrefixes(), values); + return this; + } + + @Override + public WhereBuilder addWhereValueRow(Collection<?> values) { + getWhereHandler().addValueRow(getPrologHandler().getPrefixes(), values); + return this; + } + + @Override + public List<Var> getWhereValuesVars() { + return getWhereHandler().getValuesVars(); + } + + @Override + public Map<Var, List<Node>> getWhereValuesMap() { + return getWhereHandler().getValuesMap(); + } + + @Override + public WhereBuilder clearWhereValues() { + getWhereHandler().clearValues(); + return this; + } + + @Override + public WhereBuilder addOptional(TriplePath t) + { + getWhereHandler().addOptional( t ); + return this; + } + @Override + public WhereBuilder addOptional(Triple t) { + getWhereHandler().addOptional(new TriplePath(t)); + return this; + } + + @Override + public WhereBuilder addOptional(FrontsTriple t) { + getWhereHandler().addOptional(new TriplePath(t.asTriple())); + return this; + } + + @Override + public WhereBuilder addOptional(Object s, Object p, Object o) { + getWhereHandler().addOptional( makeTriplePath( s, p, o )); + return this; + } + + @Override + public WhereBuilder addOptional(AbstractQueryBuilder<?> t) { + getWhereHandler().addOptional(t.getWhereHandler()); + return this; + } + + @Override + public WhereBuilder addFilter(Expr expr) { + getWhereHandler().addFilter(expr); + return this; + } + + @Override + public WhereBuilder addFilter(String s) throws ParseException { + getWhereHandler().addFilter(s); + return this; + } + + @Override + public WhereBuilder addSubQuery(AbstractQueryBuilder<?> subQuery) { + getWhereHandler().addSubQuery(subQuery); + return this; + } + + @Override + public WhereBuilder addUnion(AbstractQueryBuilder<?> subQuery) { + getWhereHandler().addUnion(subQuery); + return this; + } + + @Override + public WhereBuilder addGraph(Object graph, AbstractQueryBuilder<?> subQuery) { + getPrologHandler().addAll(subQuery.getPrologHandler()); + getWhereHandler().addGraph(makeNode(graph), subQuery.getWhereHandler()); + return this; + } + @Override + public WhereBuilder addGraph(Object graph, FrontsTriple triple) { + getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple.asTriple())); + return this; + } + @Override + public WhereBuilder addGraph(Object graph, Object subject, Object predicate, Object object) + { + getWhereHandler().addGraph(makeNode(graph), makeTriplePath( subject, predicate, object )); + return this; + } + @Override + public WhereBuilder addGraph(Object graph, Triple triple) { + getWhereHandler().addGraph(makeNode(graph), new TriplePath(triple)); + return this; + } + @Override + public WhereBuilder addGraph(Object graph, TriplePath triplePath) { + getWhereHandler().addGraph(makeNode(graph), triplePath ); + return this; + } + + @Override + public WhereBuilder addBind(Expr expression, Object var) { + getWhereHandler().addBind(expression, makeVar(var)); + return this; + } + + @Override + public WhereBuilder addBind(String expression, Object var) throws ParseException { + getWhereHandler().addBind(expression, makeVar(var)); + return this; + } + + @Override + public Node list(Object... objs) { + return getWhereHandler().list(objs); + } + + @Override + public WhereBuilder addMinus( AbstractQueryBuilder<?> t ) { + getWhereHandler().addMinus( t ); + return this; + } + + + @Override + public HandlerBlock getHandlerBlock() + { + return block; + } + + @Override + public String toString() { + return query.toString(); + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/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 0f45204..a85a5e6 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 @@ -25,6 +25,7 @@ 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.rewriters.BuildElementVisitor; import org.apache.jena.arq.querybuilder.rewriters.ElementRewriter; import org.apache.jena.graph.Node; import org.apache.jena.graph.NodeFactory; @@ -66,6 +67,13 @@ public class WhereHandler implements Handler { } /** + * Creates a where handler with a new query. + */ + public WhereHandler() { + this( new Query() ); + } + + /** * Get the query pattern from this where handler. * @return the query pattern */ @@ -73,6 +81,13 @@ public class WhereHandler implements Handler { { return query.getQueryPattern(); } + + /** + * @return The query this where handler is using. + */ + public Query getQuery() { + return query; + } /** * Add all where attributes from the Where Handler argument. @@ -118,7 +133,7 @@ public class WhereHandler implements Handler { * * @return the base element. */ - private Element getElement() { + public Element getElement() { Element result = query.getQueryPattern(); if (result == null) { result = getClause(); @@ -442,17 +457,17 @@ public class WhereHandler implements Handler { getElement().visit(visitor); if (! valuesHandler.isEmpty()) { - if (visitor.result instanceof ElementGroup) { - ((ElementGroup)visitor.result).addElement( valuesHandler.asElement());; + if (visitor.getResult() instanceof ElementGroup) { + ((ElementGroup)visitor.getResult()).addElement( valuesHandler.asElement());; } else { ElementGroup eg = new ElementGroup(); - eg.addElement(visitor.result); + eg.addElement(visitor.getResult()); eg.addElement( valuesHandler.asElement()); - visitor.result = eg; + visitor.setResult( eg ); } } - query.setQueryPattern( visitor.result ); + query.setQueryPattern( visitor.getResult() ); } /** @@ -565,189 +580,4 @@ public class WhereHandler implements Handler { public void clearValues() { valuesHandler.clear(); } - - - - /** - * 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/5e6c047e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/AbstractRewriter.java ---------------------------------------------------------------------- diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/AbstractRewriter.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/AbstractRewriter.java index f06a398..14baba2 100644 --- a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/AbstractRewriter.java +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/AbstractRewriter.java @@ -133,6 +133,7 @@ public class AbstractRewriter<T> { if (values.containsKey(v)) { return values.get(v); } + return v; } return n; } http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/BuildElementVisitor.java ---------------------------------------------------------------------- diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/BuildElementVisitor.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/BuildElementVisitor.java new file mode 100644 index 0000000..9a3b89a --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/rewriters/BuildElementVisitor.java @@ -0,0 +1,234 @@ +/* + * 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.rewriters; + +import java.util.List; + +import org.apache.jena.arq.querybuilder.handlers.WhereHandler; +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; + +/** + * An element visitor that does an in-place modification of the elements to + * fix union-of-one and similar issues. + * + */ +public class BuildElementVisitor implements ElementVisitor { + private Element result; + + + public Element getResult() + { + return result; + } + + public void setResult(Element result) + { + this.result = 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.getQuery().getQueryPattern() ); + } + result = el; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/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 index cc7c2ea..2620666 100644 --- 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 @@ -19,6 +19,7 @@ package org.apache.jena.arq.querybuilder.updatebuilder; import java.util.function.Function; +import org.apache.jena.arq.querybuilder.AbstractQueryBuilder; import org.apache.jena.graph.Node; import org.apache.jena.graph.Triple; import org.apache.jena.query.Query; @@ -55,17 +56,20 @@ class QuadIteratorBuilder implements ElementVisitor { 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>(){ - + private final Function<Triple,Quad> MAP = + new Function<Triple,Quad>(){ + @Override public Quad apply(Triple triple) { - return new Quad( defaultGraph, triple ); + return new Quad( defaultGraph, + AbstractQueryBuilder.checkVar( triple.getSubject()), + AbstractQueryBuilder.checkVar( triple.getPredicate()), + AbstractQueryBuilder.checkVar( triple.getObject())); } }; - + /** * Constructor. * @param defaultGraph the default graph name. @@ -74,21 +78,21 @@ class QuadIteratorBuilder implements ElementVisitor { { this.defaultGraph = defaultGraph; } - - + + @Override public void visit(ElementTriplesBlock el) { iter = iter.andThen( WrappedIterator.create(el.getPattern().getList().iterator()) - .mapWith( MAP )); + .mapWith( MAP )); } @Override public void visit(ElementPathBlock el) { - for (TriplePath pth : el.getPattern().getList()) + for (final TriplePath pth : el.getPattern().getList()) { if ( ! pth.isTriple()) { - throw new QueryParseException("Paths not permitted in data quad", -1, -1) ; + throw new QueryParseException("Paths not permitted in data quad", -1, -1) ; } } iter = iter.andThen( @@ -99,28 +103,28 @@ class QuadIteratorBuilder implements ElementVisitor { @Override public void visit(ElementFilter el) { - throw new QueryParseException("Paths not permitted in data quad", -1, -1) ; + 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) ; + 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) ; - + 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) ; + throw new QueryParseException("element data not permitted in data quad", -1, -1) ; } @Override public void visit(ElementUnion el) { - for (Element e : el.getElements()) + for (final Element e : el.getElements()) { e.visit( this ); } @@ -128,12 +132,12 @@ class QuadIteratorBuilder implements ElementVisitor { @Override public void visit(ElementOptional el) { - throw new QueryParseException("optional not permitted in data quad", -1, -1) ; + throw new QueryParseException("optional not permitted in data quad", -1, -1) ; } @Override public void visit(ElementGroup el) { - for (Element e : el.getElements()) + for (final Element e : el.getElements()) { e.visit( this ); } @@ -146,19 +150,19 @@ class QuadIteratorBuilder implements ElementVisitor { @Override public void visit(ElementNamedGraph el) { - QuadIteratorBuilder bldr = new QuadIteratorBuilder( el.getGraphNameNode()); + final 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) ; + 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) ; + throw new QueryParseException("not exists not permitted in data quad", -1, -1) ; } @Override @@ -173,8 +177,8 @@ class QuadIteratorBuilder implements ElementVisitor { @Override public void visit(ElementSubQuery el) { - Query q = el.getQuery(); + final Query q = el.getQuery(); q.getQueryPattern().visit( this ); } - + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/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 index 234de60..1403544 100644 --- 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 @@ -18,6 +18,8 @@ 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.graph.Triple; import org.apache.jena.sparql.core.Quad; @@ -39,7 +41,16 @@ public class SingleQuadHolder implements QuadHolder{ */ public SingleQuadHolder( Quad quad ) { - this.quad = quad; + if (quad.getGraph().isVariable() || quad.getSubject().isVariable() || quad.getPredicate().isVariable() || + quad.getObject().isVariable()) + { + this.quad = new Quad( AbstractQueryBuilder.checkVar( quad.getGraph()), + AbstractQueryBuilder.checkVar( quad.getSubject() ), + AbstractQueryBuilder.checkVar( quad.getPredicate()), + AbstractQueryBuilder.checkVar( quad.getObject())); + } else { + this.quad = quad; + } } /** @@ -51,10 +62,16 @@ public class SingleQuadHolder implements QuadHolder{ */ public SingleQuadHolder( Triple triple ) { - this.quad = new Quad( Quad.defaultGraphNodeGenerated, triple ); + this.quad = new Quad( Quad.defaultGraphNodeGenerated, + AbstractQueryBuilder.checkVar( triple.getSubject()), + AbstractQueryBuilder.checkVar( triple.getPredicate()), + AbstractQueryBuilder.checkVar( triple.getObject()) + ); } - + + + /** * Constructor from a triple * @param graph the graph name to use for the triple @@ -64,7 +81,7 @@ public class SingleQuadHolder implements QuadHolder{ { this.quad = new Quad( graph, triple ); } - + @Override public ExtendedIterator<Quad> getQuads() { return new SingletonIterator<Quad>(updated==null?quad:updated); @@ -76,12 +93,12 @@ public class SingleQuadHolder implements QuadHolder{ Node retval = null; if (n.isVariable()) { - Var v = Var.alloc(n); + final 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( @@ -93,5 +110,5 @@ public class SingleQuadHolder implements QuadHolder{ return this; } - + } http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/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 index b6e40e4..8403e20 100644 --- 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 @@ -23,6 +23,7 @@ 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.BuildElementVisitor; import org.apache.jena.arq.querybuilder.rewriters.ElementRewriter; import org.apache.jena.graph.Node; import org.apache.jena.graph.NodeFactory; @@ -373,14 +374,16 @@ public class WhereProcessor implements QuadHolder { * 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; - } + public WhereProcessor setVars(Map<Var, Node> values) { + if ( whereClause != null) { + /* process when values are empty as rewriter handles Node_Variable to Var translation. + * + */ ElementRewriter r = new ElementRewriter(values); whereClause.visit(r); - return r.getResult(); - + whereClause = r.getResult(); + } + return this; } @Override @@ -430,4 +433,17 @@ public class WhereProcessor implements QuadHolder { ElementMinus minus = new ElementMinus(qb.getWhereHandler().getClause()); clause.addElement(minus); } + + + /** + * @return Build the whereClause and return the element. + */ + public Element build() { + /* + * cleanup union-of-one and other similar issues. + */ + BuildElementVisitor visitor = new BuildElementVisitor(); + whereClause.visit(visitor); + return whereClause; + } } http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java ---------------------------------------------------------------------- diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java index 1df4b83..2af2e50 100644 --- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java +++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilderTest.java @@ -102,6 +102,11 @@ public class AbstractQueryBuilderTest { n = builder.makeNode(builder); LiteralLabel ll = LiteralLabelFactory.createTypedLiteral(builder); assertEquals(NodeFactory.createLiteral(ll), n); + + n = builder.makeNode( NodeFactory.createVariable("foo")); + assertTrue( n.isVariable()); + assertEquals( "foo", n.getName()); + assertTrue( n instanceof Var ); } http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/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 index e359cea..836334a 100644 --- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java +++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/UpdateBuilderTest.java @@ -307,7 +307,7 @@ public class UpdateBuilderTest { } @Test - public void testInsertAndDeleteWithVar() + public void testInsertAndDeleteWithVarReplacement() { UpdateBuilder builder = new UpdateBuilder(); Var v = Var.alloc("v"); @@ -346,6 +346,88 @@ public class UpdateBuilderTest { assertEquals( builder.makeNode("foo"), t.getObject()); } + @Test + public void testInsertAndDeleteWithVariableNodeReplacement() + { + UpdateBuilder builder = new UpdateBuilder(); + Node v = NodeFactory.createVariable("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()); + } + + @Test + public void testInsertAndDeleteWithVariableNode() + { + UpdateBuilder builder = new UpdateBuilder(); + Node v = NodeFactory.createVariable("v"); + + builder.addInsert( new Quad( g, s, v, o) ); + builder.addDelete( new Triple( s, v, o) ); + builder.addWhere( null, v, "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( v, q.getPredicate()); + assertEquals( o, q.getObject()); + assertTrue( Var.isVar(q.getPredicate())); + + quads = um.getDeleteQuads(); + assertEquals( 1, quads.size()); + q = quads.get(0); + assertEquals( Quad.defaultGraphNodeGenerated, q.getGraph()); + assertEquals( s, q.getSubject()); + assertEquals( v, q.getPredicate()); + assertEquals( o, q.getObject()); + assertTrue( Var.isVar(q.getPredicate())); + + 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( v, t.getPredicate()); + assertEquals( builder.makeNode("foo"), t.getObject()); + assertTrue( Var.isVar(t.getPredicate())); + } // testsbased on the examples /* http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/WhereBuilderContractTest.java ---------------------------------------------------------------------- diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/WhereBuilderContractTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/WhereBuilderContractTest.java new file mode 100644 index 0000000..25baf2b --- /dev/null +++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/WhereBuilderContractTest.java @@ -0,0 +1,53 @@ +/* + * 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 org.junit.runner.RunWith; +import org.xenei.junit.contract.Contract; +import org.xenei.junit.contract.ContractImpl; +import org.xenei.junit.contract.ContractSuite; +import org.xenei.junit.contract.IProducer; + +@RunWith(ContractSuite.class) +@ContractImpl(WhereBuilder.class) +public class WhereBuilderContractTest { + + // create the producer to inject + private IProducer<WhereBuilder> producer = new IProducer<WhereBuilder>() { + + @Override + public WhereBuilder newInstance() { + return new WhereBuilder(); + } + + @Override + public void cleanUp() { + // no cleanup required + } + + }; + + public WhereBuilderContractTest() { + } + + @Contract.Inject + public IProducer<WhereBuilder> getProducer() { + return producer; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierTest.java ---------------------------------------------------------------------- diff --git a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierTest.java b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierTest.java index d144395..2cbc76e 100644 --- a/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierTest.java +++ b/jena-extras/jena-querybuilder/src/test/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierTest.java @@ -18,14 +18,24 @@ package org.apache.jena.arq.querybuilder.clauses; import static org.junit.Assert.assertFalse; + +import java.util.List; + import org.apache.jena.arq.querybuilder.AbstractQueryBuilder; import org.apache.jena.arq.querybuilder.Order; import org.apache.jena.arq.querybuilder.clauses.SolutionModifierClause; +import org.apache.jena.graph.Node; +import org.apache.jena.graph.NodeFactory; +import org.apache.jena.query.Query; +import org.apache.jena.query.SortCondition; import org.apache.jena.sparql.core.Var; +import org.apache.jena.sparql.core.VarExprList; import org.apache.jena.sparql.expr.E_Random; import org.apache.jena.sparql.expr.Expr; +import org.apache.jena.sparql.expr.ExprVar; import org.apache.jena.sparql.lang.sparql_11.ParseException; import org.junit.After; +import org.junit.Assert; import org.xenei.junit.contract.Contract; import org.xenei.junit.contract.ContractTest; import org.xenei.junit.contract.IProducer; @@ -55,32 +65,51 @@ public class SolutionModifierTest<T extends SolutionModifierClause<?>> extends A public void testAddOrderByString() { SolutionModifierClause<?> solutionModifier = getProducer().newInstance(); AbstractQueryBuilder<?> builder = solutionModifier.addOrderBy("foo"); - assertContainsRegex(ORDER_BY + var("foo"), builder.buildString()); + + List<SortCondition> lst = builder.build().getOrderBy(); + Assert.assertEquals( 1, lst.size()); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc("foo")), Query.ORDER_DEFAULT ), lst.get(0)); builder = solutionModifier.addOrderBy("bar"); - assertContainsRegex(ORDER_BY + var("foo") + SPACE + var("bar"), builder.buildString()); + lst = builder.build().getOrderBy(); + Assert.assertEquals( 2, lst.size()); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc("foo")), Query.ORDER_DEFAULT ), lst.get(0)); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc("bar")), Query.ORDER_DEFAULT ), lst.get(1)); + } @ContractTest public void testAddOrderByStringAscending() { SolutionModifierClause<?> solutionModifier = getProducer().newInstance(); AbstractQueryBuilder<?> builder = solutionModifier.addOrderBy("foo", Order.ASCENDING); - assertContainsRegex(ORDER_BY + "ASC" + OPEN_PAREN + var("foo") + CLOSE_PAREN, builder.buildString()); + + List<SortCondition> lst = builder.build().getOrderBy(); + Assert.assertEquals( 1, lst.size()); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc("foo")), Query.ORDER_ASCENDING ), lst.get(0)); + builder = solutionModifier.addOrderBy("bar"); - assertContainsRegex(ORDER_BY + "ASC" + OPEN_PAREN + var("foo") + CLOSE_PAREN + SPACE + var("bar"), - builder.buildString()); + lst = builder.build().getOrderBy(); + Assert.assertEquals( 2, lst.size()); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc("foo")), Query.ORDER_ASCENDING ), lst.get(0)); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc("bar")), Query.ORDER_DEFAULT ), lst.get(1)); + } @ContractTest public void testAddOrderByStringDescending() { SolutionModifierClause<?> solutionModifier = getProducer().newInstance(); AbstractQueryBuilder<?> builder = solutionModifier.addOrderBy("foo", Order.DESCENDING); - assertContainsRegex(ORDER_BY + "DESC" + OPEN_PAREN + var("foo") + CLOSE_PAREN, builder.buildString()); + + List<SortCondition> lst = builder.build().getOrderBy(); + Assert.assertEquals( 1, lst.size()); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc("foo")), Query.ORDER_DESCENDING ), lst.get(0)); builder = solutionModifier.addOrderBy("bar"); - assertContainsRegex(ORDER_BY + "DESC" + OPEN_PAREN + var("foo") + CLOSE_PAREN + SPACE + var("bar"), - builder.buildString()); + lst = builder.build().getOrderBy(); + Assert.assertEquals( 2, lst.size()); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc("foo")), Query.ORDER_DESCENDING ), lst.get(0)); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc("bar")), Query.ORDER_DEFAULT ), lst.get(1)); } @ContractTest @@ -143,12 +172,25 @@ public class SolutionModifierTest<T extends SolutionModifierClause<?>> extends A @ContractTest public void testAddGroupByVar() { + Var foo = Var.alloc("foo"); SolutionModifierClause<?> solutionModifier = getProducer().newInstance(); - AbstractQueryBuilder<?> builder = solutionModifier.addGroupBy(Var.alloc("foo")); - assertContainsRegex(GROUP_BY + var("foo"), builder.buildString()); + AbstractQueryBuilder<?> builder = solutionModifier.addGroupBy(foo); + + VarExprList groupBy = builder.build().getGroupBy(); + Assert.assertEquals( 1, groupBy.size()); + Assert.assertEquals( foo, groupBy.getVars().get(0)); + Assert.assertNull( groupBy.getExpr( foo )); + builder = solutionModifier.addGroupBy("bar"); - assertContainsRegex(GROUP_BY + var("foo") + SPACE + var("bar"), builder.buildString()); + groupBy = builder.build().getGroupBy(); + Assert.assertEquals( 2, groupBy.size()); + Assert.assertEquals( foo, groupBy.getVars().get(0)); + Assert.assertNull( groupBy.getExpr( foo )); + + Assert.assertEquals( Var.alloc("bar"), groupBy.getVars().get(1)); + Assert.assertNull( groupBy.getExpr( Var.alloc("bar") )); + } @ContractTest @@ -236,12 +278,39 @@ public class SolutionModifierTest<T extends SolutionModifierClause<?>> extends A SolutionModifierClause<?> solutionModifier = getProducer().newInstance(); AbstractQueryBuilder<?> builder = solutionModifier.addGroupBy("?v"); - String[] s = byLine(builder); - assertContainsRegex(GROUP_BY + var("v"), s); + VarExprList groupBy = builder.build().getGroupBy(); + Assert.assertEquals( 1, groupBy.size()); + Assert.assertEquals( Var.alloc( "v"), groupBy.getVars().get(0)); + Assert.assertNull( groupBy.getExpr( Var.alloc( "v"))); + builder.setVar(v, Var.alloc("v2")); - s = byLine(builder); - assertContainsRegex(GROUP_BY + var("v2"), s); + groupBy = builder.build().getGroupBy(); + Assert.assertEquals( 1, groupBy.size()); + Assert.assertEquals( Var.alloc( "v2"), groupBy.getVars().get(0)); + Assert.assertNull( groupBy.getExpr( Var.alloc( "v2"))); + builder.setVar(v, Var.alloc("v2")); + + } + + @ContractTest + public void testSetVarsGroupBy_Node_Variable() { + Node v = NodeFactory.createVariable("v"); + SolutionModifierClause<?> solutionModifier = getProducer().newInstance(); + AbstractQueryBuilder<?> builder = solutionModifier.addGroupBy(v); + + VarExprList groupBy = builder.build().getGroupBy(); + Assert.assertEquals( 1, groupBy.size()); + Assert.assertEquals( Var.alloc( "v"), groupBy.getVars().get(0)); + Assert.assertNull( groupBy.getExpr( Var.alloc( "v"))); + + + builder.setVar(v, NodeFactory.createVariable("v2")); + groupBy = builder.build().getGroupBy(); + Assert.assertEquals( 1, groupBy.size()); + Assert.assertEquals( Var.alloc( "v2"), groupBy.getVars().get(0)); + Assert.assertNull( groupBy.getExpr( Var.alloc( "v2"))); + } @ContractTest @@ -250,12 +319,30 @@ public class SolutionModifierTest<T extends SolutionModifierClause<?>> extends A SolutionModifierClause<?> solutionModifier = getProducer().newInstance(); AbstractQueryBuilder<?> builder = solutionModifier.addHaving("?v"); - String[] s = byLine(builder); - assertContainsRegex(HAVING + var("v"), s); + List<Expr> exprs = builder.build().getHavingExprs(); + Assert.assertEquals( 1, exprs.size()); + Assert.assertEquals( new ExprVar( Var.alloc(v)), exprs.get(0)); builder.setVar(v, Var.alloc("v2")); - s = byLine(builder); - assertContainsRegex(HAVING + var("v2"), s); + exprs = builder.build().getHavingExprs(); + Assert.assertEquals( 1, exprs.size()); + Assert.assertEquals( new ExprVar( Var.alloc("v2")), exprs.get(0)); + } + + @ContractTest + public void testSetVarsHaving_Node_Variable() throws ParseException { + Node v = NodeFactory.createVariable("v"); + SolutionModifierClause<?> solutionModifier = getProducer().newInstance(); + AbstractQueryBuilder<?> builder = solutionModifier.addHaving(v); + + List<Expr> exprs = builder.build().getHavingExprs(); + Assert.assertEquals( 1, exprs.size()); + Assert.assertEquals( new ExprVar( Var.alloc(v)), exprs.get(0)); + + builder.setVar(v, Var.alloc("v2")); + exprs = builder.build().getHavingExprs(); + Assert.assertEquals( 1, exprs.size()); + Assert.assertEquals( new ExprVar( Var.alloc("v2")), exprs.get(0)); } @ContractTest @@ -264,12 +351,30 @@ public class SolutionModifierTest<T extends SolutionModifierClause<?>> extends A SolutionModifierClause<?> solutionModifier = getProducer().newInstance(); AbstractQueryBuilder<?> builder = solutionModifier.addOrderBy("?v"); - String[] s = byLine(builder); - assertContainsRegex(ORDER_BY + var("v"), s); + List<SortCondition> lst = builder.build().getOrderBy(); + Assert.assertEquals( 1, lst.size()); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc(v)), Query.ORDER_DEFAULT ), lst.get(0)); builder.setVar(v, Var.alloc("v2")); - s = byLine(builder); - assertContainsRegex(ORDER_BY + var("v2"), s); + lst = builder.build().getOrderBy(); + Assert.assertEquals( 1, lst.size()); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc("v2")), Query.ORDER_DEFAULT ), lst.get(0)); + } + @ContractTest + public void testSetVarsOrderBy_NodeVariable() { + Node v = NodeFactory.createVariable("v"); + SolutionModifierClause<?> solutionModifier = getProducer().newInstance(); + AbstractQueryBuilder<?> builder = solutionModifier.addOrderBy(v); + + List<SortCondition> lst = builder.build().getOrderBy(); + Assert.assertEquals( 1, lst.size()); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc(v)), Query.ORDER_DEFAULT ), lst.get(0)); + + builder.setVar(v, Var.alloc("v2")); + lst = builder.build().getOrderBy(); + Assert.assertEquals( 1, lst.size()); + Assert.assertEquals( new SortCondition( new ExprVar( Var.alloc("v2")), Query.ORDER_DEFAULT ), lst.get(0)); + } } http://git-wip-us.apache.org/repos/asf/jena/blob/5e6c047e/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 a52bcac..42c8ef4 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 @@ -36,12 +36,16 @@ import org.apache.jena.shared.impl.PrefixMappingImpl; import org.apache.jena.sparql.core.TriplePath; import org.apache.jena.sparql.core.Var; import org.apache.jena.sparql.engine.binding.BindingHashMap; +import org.apache.jena.sparql.expr.E_LessThan; import org.apache.jena.sparql.expr.E_Random; +import org.apache.jena.sparql.expr.ExprVar; +import org.apache.jena.sparql.expr.nodevalue.NodeValueInteger; import org.apache.jena.sparql.lang.sparql_11.ParseException; import org.apache.jena.sparql.path.Path; import org.apache.jena.sparql.path.PathParser; import org.apache.jena.sparql.syntax.ElementBind; import org.apache.jena.sparql.syntax.ElementData; +import org.apache.jena.sparql.syntax.ElementFilter; import org.apache.jena.sparql.syntax.ElementMinus; import org.apache.jena.sparql.syntax.ElementNamedGraph; import org.apache.jena.sparql.syntax.ElementOptional; @@ -200,15 +204,49 @@ public class WhereClauseTest<T extends WhereClause<?>> extends assertTrue( visitor.matching ); } + + @ContractTest + public void testAddOptionalGroupPattern_VariableNode() throws ParseException { + + Node s = NodeFactory.createVariable("s"); + Node q = NodeFactory.createURI( "urn:q" ); + Node v = NodeFactory.createURI( "urn:v" ); + Var x = Var.alloc("x"); + Node n123 = NodeFactory.createLiteral(LiteralLabelFactory.createTypedLiteral(123)); + + SelectBuilder pattern = new SelectBuilder(); + pattern.addWhere( new Triple( s, q, n123 ) ); + pattern.addWhere( new Triple( s, v, x)); + + + WhereClause<?> whereClause = getProducer().newInstance(); + AbstractQueryBuilder<?> builder = whereClause.addOptional( pattern ); + + ElementPathBlock epb = new ElementPathBlock(); + ElementOptional optional = new ElementOptional(epb); + TriplePath tp = new TriplePath( new Triple(Var.alloc(s), q, n123)); + epb.addTriplePath( tp ); + tp = new TriplePath( new Triple(Var.alloc(s), v, x)); + epb.addTriplePath( tp ); + + WhereValidator visitor = new WhereValidator( optional ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + + } @ContractTest public void testAddFilter() throws ParseException { WhereClause<?> whereClause = getProducer().newInstance(); AbstractQueryBuilder<?> builder = whereClause.addFilter("?one<10"); - assertContainsRegex(WHERE + OPEN_CURLY + "FILTER" + OPT_SPACE - + OPEN_PAREN + var("one") + OPT_SPACE + LT + OPT_SPACE + "10" - + CLOSE_PAREN + CLOSE_CURLY, builder.buildString()); + E_LessThan lt = new E_LessThan( new ExprVar( Var.alloc( "one")), new NodeValueInteger( 10 )); + ElementFilter ef = new ElementFilter(lt); + + WhereValidator visitor = new WhereValidator( ef ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + } @ContractTest @@ -257,30 +295,99 @@ public class WhereClauseTest<T extends WhereClause<?>> extends @ContractTest public void testSetVarsInTriple() { Var v = Var.alloc("v"); + Node one = NodeFactory.createURI( "one"); + Node two = NodeFactory.createURI( "two"); + Node three = NodeFactory.createURI( "three"); + Node four = NodeFactory.createURI( "four"); + WhereClause<?> whereClause = getProducer().newInstance(); AbstractQueryBuilder<?> builder = whereClause.addWhere(new Triple( - NodeFactory.createURI("one"), NodeFactory.createURI("two"), v)); - assertContainsRegex(WHERE + OPEN_CURLY + uri("one") + SPACE - + uri("two") + SPACE + var("v") + OPT_SPACE - + CLOSE_CURLY, builder.buildString()); + one, two, v)); + + TriplePath tp = new TriplePath( new Triple( one, two, v )); + ElementPathBlock epb = new ElementPathBlock(); + epb.addTriple(tp); + WhereValidator visitor = new WhereValidator( epb ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + + builder.setVar(v, three); - builder.setVar(v, NodeFactory.createURI("three")); + tp = new TriplePath( new Triple( one, two, three )); + epb = new ElementPathBlock(); + epb.addTriple(tp); + visitor = new WhereValidator( epb ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + - assertContainsRegex(WHERE + OPEN_CURLY + uri("one") + SPACE - + uri("two") + SPACE + uri("three") + OPT_SPACE - + CLOSE_CURLY, builder.buildString()); + builder.setVar(v, four); - builder.setVar(v, NodeFactory.createURI("four")); + tp = new TriplePath( new Triple( one, two, four )); + epb = new ElementPathBlock(); + epb.addTriple(tp); + visitor = new WhereValidator( epb ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + - assertContainsRegex(WHERE + OPEN_CURLY + uri("one") + SPACE - + uri("two") + SPACE + uri("four") + OPT_SPACE - + CLOSE_CURLY, builder.buildString()); + builder.setVar(v, null); + + tp = new TriplePath( new Triple( one, two, v )); + epb = new ElementPathBlock(); + epb.addTriple(tp); + visitor = new WhereValidator( epb ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + } + + @ContractTest + public void testSetVarsInTriple_Node_Variable() { + Node v = NodeFactory.createVariable("v"); + Node one = NodeFactory.createURI( "one"); + Node two = NodeFactory.createURI( "two"); + Node three = NodeFactory.createURI( "three"); + Node four = NodeFactory.createURI( "four"); + + WhereClause<?> whereClause = getProducer().newInstance(); + AbstractQueryBuilder<?> builder = whereClause.addWhere(new Triple( + one, two, v)); + + TriplePath tp = new TriplePath( new Triple( one, two, Var.alloc(v) )); + ElementPathBlock epb = new ElementPathBlock(); + epb.addTriple(tp); + WhereValidator visitor = new WhereValidator( epb ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + + builder.setVar(v, three); + + tp = new TriplePath( new Triple( one, two, three )); + epb = new ElementPathBlock(); + epb.addTriple(tp); + visitor = new WhereValidator( epb ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + + + builder.setVar(v, four); + + tp = new TriplePath( new Triple( one, two, four )); + epb = new ElementPathBlock(); + epb.addTriple(tp); + visitor = new WhereValidator( epb ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + builder.setVar(v, null); - assertContainsRegex(WHERE + OPEN_CURLY + uri("one") + SPACE - + uri("two") + SPACE + var("v") + OPT_SPACE - + CLOSE_CURLY, builder.buildString()); + tp = new TriplePath( new Triple( one, two, Var.alloc("v") )); + epb = new ElementPathBlock(); + epb.addTriple(tp); + visitor = new WhereValidator( epb ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); } @@ -320,6 +427,38 @@ public class WhereClauseTest<T extends WhereClause<?>> extends + uri("three") + OPT_SPACE + CLOSE_CURLY + CLOSE_CURLY, builder.buildString()); } + + @ContractTest + public void testSetVarsInOptional_Node_Variable() { + Node v = NodeFactory.createVariable("v"); + Node one = NodeFactory.createURI("one"); + Node two = NodeFactory.createURI("two"); + Node three = NodeFactory.createURI("three"); + + WhereClause<?> whereClause = getProducer().newInstance(); + AbstractQueryBuilder<?> builder = whereClause.addOptional(new Triple( + one, two, v)); + + ElementPathBlock epb = new ElementPathBlock(); + ElementOptional optional = new ElementOptional(epb); + TriplePath tp = new TriplePath( new Triple(one, two, Var.alloc(v))); + epb.addTriplePath( tp ); + + WhereValidator visitor = new WhereValidator( optional ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + + builder.setVar(v, three); + epb = new ElementPathBlock(); + optional = new ElementOptional(epb); + tp = new TriplePath( new Triple(one, two, three)); + epb.addTriplePath( tp ); + + visitor = new WhereValidator( optional ); + builder.build().getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + + } @ContractTest public void testSetVarsInSubQuery() { @@ -338,6 +477,24 @@ public class WhereClauseTest<T extends WhereClause<?>> extends + uri("two") + SPACE + uri("three") + CLOSE_CURLY, builder.buildString()); } + + @ContractTest + public void testSetVarsInSubQuery_Node_Variable() { + Node v = NodeFactory.createVariable("v"); + SelectBuilder sb = new SelectBuilder(); + sb.addPrefix("pfx", "uri").addWhere("<one>", "<two>", v); + WhereClause<?> whereClause = getProducer().newInstance(); + AbstractQueryBuilder<?> builder = whereClause.addSubQuery(sb); + + assertContainsRegex(WHERE + OPEN_CURLY + uri("one") + SPACE + + uri("two") + SPACE + var("v") + CLOSE_CURLY, + builder.buildString()); + + builder.setVar(v, NodeFactory.createURI("three")); + assertContainsRegex(WHERE + OPEN_CURLY + uri("one") + SPACE + + uri("two") + SPACE + uri("three") + CLOSE_CURLY, + builder.buildString()); + } @ContractTest public void testSetVarsInUnion() { @@ -387,6 +544,55 @@ public class WhereClauseTest<T extends WhereClause<?>> extends assertTrue( visitor.matching ); } + + @ContractTest + public void testSetVarsInUnion_Node_Variable() { + Node v = NodeFactory.createVariable("v"); + SelectBuilder sb1 = new SelectBuilder() + .addPrefix("pfx", "uri").addWhere("<one>", "<two>", v); + WhereClause<?> whereClause = getProducer().newInstance(); + whereClause.addUnion(sb1); + SelectBuilder sb2 = new SelectBuilder().addWhere("<uno>", "<dos>", "<tres>"); + AbstractQueryBuilder<?> builder = whereClause.addUnion(sb2); + Query query = builder.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, Var.alloc(v)); + 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")); + 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 public void testBindStringVar() throws ParseException { @@ -409,6 +615,28 @@ public class WhereClauseTest<T extends WhereClause<?>> extends assertTrue( visitor.matching ); } + + @ContractTest + public void testBindStringVar_Node_Variable() throws ParseException { + Node v = NodeFactory.createVariable("foo"); + WhereClause<?> whereClause = getProducer().newInstance(); + AbstractQueryBuilder<?> builder = whereClause.addBind("rand()", v); + Query query = builder.build(); + + ElementBind bind = new ElementBind( Var.alloc(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 ); + + } @ContractTest public void testBindExprVar() { @@ -434,6 +662,28 @@ public class WhereClauseTest<T extends WhereClause<?>> extends } @ContractTest + public void testBindExprVar_Node_Variable() { + Node v = NodeFactory.createVariable("foo"); + WhereClause<?> whereClause = getProducer().newInstance(); + AbstractQueryBuilder<?> builder = whereClause + .addBind(new E_Random(), v); + Query query = builder.build(); + + + 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 = builder.build(); + + visitor = new WhereValidator( new ElementTriplesBlock() ); + query.getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + + } + @ContractTest public void testList() { WhereClause<?> whereClause = getProducer().newInstance(); AbstractQueryBuilder<?> builder = whereClause.addWhere(whereClause.list( "<one>", "?two", "'three'"), @@ -442,7 +692,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends Query query = builder.build(); Node one = NodeFactory.createURI("one"); - Node two = Var.alloc("two").asNode(); + Var two = Var.alloc("two"); Node three = NodeFactory.createLiteral( "three"); Node foo = NodeFactory.createURI("foo"); Node bar = NodeFactory.createURI("bar"); @@ -576,7 +826,6 @@ public class WhereClauseTest<T extends WhereClause<?>> extends @ContractTest public void testAddWhereValueVar_var() { - final Var v = Var.alloc("v"); WhereClause<?> whereClause = getProducer().newInstance(); AbstractQueryBuilder<?> builder = whereClause.addWhereValueVar( "?v" ); @@ -584,17 +833,17 @@ public class WhereClauseTest<T extends WhereClause<?>> extends Query query = builder.build(); ElementData edat = new ElementData(); - edat.add( v ); + edat.add( Var.alloc("v") ); WhereValidator visitor = new WhereValidator( edat ); query.getQueryPattern().visit( visitor ); assertTrue( visitor.matching ); - } + } @ContractTest public void testAddWhereValueVar_var_values() { - final Var v = Var.alloc("v"); + WhereClause<?> whereClause = getProducer().newInstance(); AbstractQueryBuilder<?> builder = whereClause.addWhereValueVar( "?v", "<one>" ); @@ -602,6 +851,7 @@ public class WhereClauseTest<T extends WhereClause<?>> extends Query query = builder.build(); BindingHashMap binding = new BindingHashMap(); + final Var v = Var.alloc("v"); binding.add( v, NodeFactory.createURI( "one" )); ElementData edat = new ElementData(); edat.add( v ); @@ -644,6 +894,38 @@ public class WhereClauseTest<T extends WhereClause<?>> extends } @ContractTest + public void testAddWhereValueVars_Node_Variable() + { + + Map<Object,List<?>> map = new HashMap<Object, List<?>>(); + + map.put( NodeFactory.createVariable("v"), Arrays.asList( "<one>", "<two>")); + map.put( "?x", Arrays.asList( "three", "four")); + + WhereClause<?> whereClause = getProducer().newInstance(); + AbstractQueryBuilder<?> builder = whereClause.addWhereValueVars( map ); + + Query query = builder.build(); + + Var x = Var.alloc("x"); + Var v = Var.alloc("v"); + ElementData edat = new ElementData(); + edat.add( x ); + edat.add( v ); + BindingHashMap binding = new BindingHashMap(); + binding.add( v, NodeFactory.createURI( "one" )); + binding.add( x, NodeFactory.createLiteral("three")); + edat.add( binding ); + binding = new BindingHashMap(); + binding.add( v, NodeFactory.createURI( "two" )); + binding.add( x, NodeFactory.createLiteral("four")); + edat.add( binding ); + + WhereValidator visitor = new WhereValidator( edat ); + query.getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + } + @ContractTest public void testAddWhereValueRow_array() { final Var v = Var.alloc("v"); @@ -675,6 +957,37 @@ public class WhereClauseTest<T extends WhereClause<?>> extends } @ContractTest + public void testAddWhereValueRow_array_Node_Variable() + { + + WhereClause<?> whereClause = getProducer().newInstance(); + whereClause = (WhereClause<?>) whereClause.addWhereValueVar( NodeFactory.createVariable("v") ); + whereClause = (WhereClause<?>) whereClause.addWhereValueVar( NodeFactory.createVariable("x") ); + whereClause = (WhereClause<?>) whereClause.addWhereValueRow( "<one>", "three" ); + AbstractQueryBuilder<?> builder = whereClause.addWhereValueRow( "<two>", "four" ); + + Query query = builder.build(); + + ElementData edat = new ElementData(); + final Var v = Var.alloc("v"); + final Var x = Var.alloc("x"); + edat.add( v ); + edat.add( x ); + BindingHashMap binding = new BindingHashMap(); + binding.add( v, NodeFactory.createURI( "one" )); + binding.add( x, NodeFactory.createLiteral("three")); + edat.add( binding ); + binding = new BindingHashMap(); + binding.add( v, NodeFactory.createURI( "two" )); + binding.add( x, NodeFactory.createLiteral("four")); + edat.add( binding ); + + WhereValidator visitor = new WhereValidator( edat ); + query.getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + } + + @ContractTest public void testAddWhereValueRow_collection() { final Var v = Var.alloc("v"); @@ -706,6 +1019,37 @@ public class WhereClauseTest<T extends WhereClause<?>> extends } @ContractTest + public void testAddWhereValueRow_collection_Node_Variable() + { + WhereClause<?> whereClause = getProducer().newInstance(); + whereClause = (WhereClause<?>) whereClause.addWhereValueVar( NodeFactory.createVariable("v") ); + whereClause = (WhereClause<?>) whereClause.addWhereValueVar( NodeFactory.createVariable("x") ); + whereClause = (WhereClause<?>) whereClause.addWhereValueRow( Arrays.asList("<one>", "three") ); + AbstractQueryBuilder<?> builder = whereClause.addWhereValueRow( Arrays.asList("<two>", "four") ); + + Query query = builder.build(); + + ElementData edat = new ElementData(); + final Var v = Var.alloc("v"); + final Var x = Var.alloc("x"); + + edat.add( v ); + edat.add( x ); + BindingHashMap binding = new BindingHashMap(); + binding.add( v, NodeFactory.createURI( "one" )); + binding.add( x, NodeFactory.createLiteral("three")); + edat.add( binding ); + binding = new BindingHashMap(); + binding.add( v, NodeFactory.createURI( "two" )); + binding.add( x, NodeFactory.createLiteral("four")); + edat.add( binding ); + + WhereValidator visitor = new WhereValidator( edat ); + query.getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + } + + @ContractTest public void testSetVarsInWhereValues() throws ParseException { Var v = Var.alloc("v"); Node value = NodeFactory.createLiteral(LiteralLabelFactory.createTypedLiteral(10)); @@ -736,6 +1080,34 @@ public class WhereClauseTest<T extends WhereClause<?>> extends } @ContractTest + public void testSetVarsInWhereValues_NodeVariable() throws ParseException { + Node v = NodeFactory.createVariable("v"); + Node value = NodeFactory.createLiteral(LiteralLabelFactory.createTypedLiteral(10)); + + WhereClause<?> whereClause = getProducer().newInstance(); + AbstractQueryBuilder<?> builder = whereClause.addWhereValueVar( "?x", "<one>", "?v"); + + builder.setVar(v, value ); + + Query query = builder.build(); + + ElementData edat = new ElementData(); + Var x = Var.alloc("x"); + edat.add( x ); + + BindingHashMap binding = new BindingHashMap(); + binding.add( x, NodeFactory.createURI( "one" )); + edat.add( binding ); + binding = new BindingHashMap(); + binding.add( x, value); + edat.add( binding ); + + WhereValidator visitor = new WhereValidator( edat ); + query.getQueryPattern().visit( visitor ); + assertTrue( visitor.matching ); + } + + @ContractTest public void testDataQuery() { // test that the getVars getMap and clear methods work. Object o = "?x";
