| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.jena.arq.querybuilder; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.function.Function; |
| |
| import org.apache.jena.arq.querybuilder.clauses.PrologClause; |
| import org.apache.jena.arq.querybuilder.clauses.WhereClause; |
| import org.apache.jena.arq.querybuilder.handlers.WhereHandler; |
| import org.apache.jena.arq.querybuilder.updatebuilder.CollectionQuadHolder; |
| import org.apache.jena.arq.querybuilder.updatebuilder.ModelQuadHolder; |
| import org.apache.jena.arq.querybuilder.updatebuilder.PrefixHandler; |
| import org.apache.jena.arq.querybuilder.updatebuilder.QBQuadHolder; |
| import org.apache.jena.arq.querybuilder.updatebuilder.QuadCollectionHolder; |
| import org.apache.jena.arq.querybuilder.updatebuilder.QuadHolder; |
| import org.apache.jena.arq.querybuilder.updatebuilder.SingleQuadHolder; |
| import org.apache.jena.arq.querybuilder.updatebuilder.WhereQuadHolder; |
| import org.apache.jena.graph.FrontsTriple; |
| import org.apache.jena.graph.Node; |
| import org.apache.jena.graph.NodeFactory; |
| import org.apache.jena.graph.Triple; |
| import org.apache.jena.query.QueryParseException; |
| import org.apache.jena.rdf.model.Model; |
| import org.apache.jena.rdf.model.Resource; |
| import org.apache.jena.shared.PrefixMapping; |
| import org.apache.jena.sparql.core.Quad; |
| import org.apache.jena.sparql.core.TriplePath; |
| import org.apache.jena.sparql.core.Var; |
| import org.apache.jena.sparql.expr.Expr; |
| import org.apache.jena.sparql.modify.request.QuadAcc; |
| import org.apache.jena.sparql.modify.request.QuadDataAcc; |
| import org.apache.jena.sparql.modify.request.UpdateDataDelete; |
| import org.apache.jena.sparql.modify.request.UpdateDataInsert; |
| import org.apache.jena.sparql.modify.request.UpdateDeleteWhere; |
| import org.apache.jena.sparql.modify.request.UpdateModify; |
| import org.apache.jena.sparql.path.Path; |
| import org.apache.jena.update.Update; |
| import org.apache.jena.update.UpdateRequest; |
| import org.apache.jena.util.iterator.ExtendedIterator; |
| import org.apache.jena.util.iterator.NiceIterator; |
| import org.apache.jena.vocabulary.RDF; |
| |
| /** |
| * Class to build update requests. |
| * |
| */ |
| public class UpdateBuilder { |
| |
| private final PrefixHandler prefixHandler; |
| private final WhereQuadHolder whereProcessor; |
| private List<QuadHolder> inserts = new ArrayList<QuadHolder>(); |
| private List<QuadHolder> deletes = new ArrayList<QuadHolder>(); |
| private Map<Var, Node> values; |
| private Node with; |
| |
| /** |
| * Creates an UpdateBuilder with an empty prefix mapping. |
| */ |
| public UpdateBuilder() { |
| this.prefixHandler = new PrefixHandler(); |
| this.whereProcessor = new WhereQuadHolder(prefixHandler); |
| this.values = new HashMap<Var, Node>(); |
| this.with = null; |
| } |
| |
| /** |
| * Creates an UpdateBuilder with the prefixes defined in the prolog clause. |
| * <b>May modify the contents of the prefix mapping in the prolog handler</b> |
| * |
| * @param prologClause the default prefixes for this builder. |
| */ |
| public UpdateBuilder(PrologClause<?> prologClause) { |
| this(prologClause.getPrologHandler().getPrefixes()); |
| } |
| |
| /** |
| * Creates an UpdateBuilder with the specified PrefixMapping. <b>May modify the |
| * contents of the prefix mapping</b> |
| * |
| * @param pMap the prefix mapping to use. |
| */ |
| public UpdateBuilder(PrefixMapping pMap) { |
| this.prefixHandler = new PrefixHandler(pMap); |
| this.whereProcessor = new WhereQuadHolder(prefixHandler); |
| this.values = new HashMap<Var, Node>(); |
| this.with = null; |
| } |
| |
| /** |
| * Convert a collection of QuadHolder to an iterator on Quads. |
| * |
| * @param holders the Collection of QuadHolder objects |
| * @return an iterator over the Quads. |
| */ |
| private ExtendedIterator<Quad> getQuads(Collection<QuadHolder> holders) { |
| ExtendedIterator<Quad> result = NiceIterator.emptyIterator(); |
| for (QuadHolder holder : holders) { |
| result = result.andThen(holder.setValues(values).getQuads()); |
| } |
| return result; |
| } |
| |
| /** |
| * Checks that no deletes or inserts have been added to the builder. |
| * @return true if there are no delete or insert statements. |
| */ |
| public boolean isEmpty() { |
| return deletes.isEmpty() && inserts.isEmpty(); |
| } |
| |
| /** |
| * Build the update. |
| * |
| * <b>Note: the update does not include the prefix statements</b> use |
| * buildRequest() or appendTo() methods to include the prefix statements. |
| * |
| * @return the update. |
| */ |
| public Update build() { |
| |
| if (isEmpty()) { |
| throw new IllegalStateException("At least one delete or insert must be specified"); |
| } |
| |
| if (whereProcessor.isEmpty()) { |
| return buildNoWhere(); |
| } |
| return buildWhere(); |
| } |
| |
| /** |
| * Build as an UpdateRequest with prefix mapping set. |
| * |
| * @return a new UpdateRequest |
| */ |
| public UpdateRequest buildRequest() { |
| UpdateRequest req = new UpdateRequest(build()); |
| req.setPrefixMapping(prefixHandler.getPrefixes()); |
| return req; |
| } |
| |
| /** |
| * Appends the new Update to the UpdateRequest. |
| * |
| * @param req the UpdateRequest to append this Update to. |
| * @return the req parameter for chaining. |
| */ |
| public UpdateRequest appendTo(UpdateRequest req) { |
| req.add(build()); |
| for (Map.Entry<String, String> entry : prefixHandler.getPrefixes().getNsPrefixMap().entrySet()) { |
| req.setPrefix(entry.getKey(), entry.getValue()); |
| } |
| return req; |
| } |
| |
| // build updates without where clauses |
| private Update buildNoWhere() { |
| if (inserts.isEmpty()) { |
| QuadDataAcc quadData = new QuadDataAcc(getQuads(deletes).mapWith(new Function<Quad, Quad>() { |
| @Override |
| public Quad apply(Quad arg0) { |
| return check(arg0); |
| } |
| }).toList()); |
| return new UpdateDataDelete(quadData); |
| } |
| if (deletes.isEmpty()) { |
| QuadDataAcc quadData = new QuadDataAcc(getQuads(inserts).mapWith(new Function<Quad, Quad>() { |
| |
| @Override |
| public Quad apply(Quad t) { |
| return check(t); |
| } |
| |
| }).toList()); |
| return new UpdateDataInsert(quadData); |
| } |
| |
| throw new IllegalStateException("Can not have both insert and delete without a where clause"); |
| } |
| |
| // build updates with where clauses |
| private Update buildWhere() { |
| |
| UpdateModify retval = new UpdateModify(); |
| if (with != null) { |
| Node graph = values.get(with); |
| if (graph == null) { |
| graph = with; |
| } |
| retval.setWithIRI(graph); |
| } |
| QuadAcc acc; |
| Iterator<Quad> iter; |
| |
| if (!inserts.isEmpty()) { |
| retval.setHasInsertClause(true); |
| acc = retval.getInsertAcc(); |
| iter = getQuads(inserts); |
| while (iter.hasNext()) { |
| acc.addQuad(iter.next()); |
| } |
| } |
| if (!deletes.isEmpty()) { |
| retval.setHasDeleteClause(true); |
| acc = retval.getDeleteAcc(); |
| |
| iter = getQuads(deletes); |
| while (iter.hasNext()) { |
| acc.addQuad(iter.next()); |
| } |
| } |
| |
| retval.setElement(whereProcessor.setVars(values).build()); |
| |
| return retval; |
| |
| } |
| |
| /** |
| * Make a triple path from the objects. |
| * |
| * For subject, predicate and objects nodes |
| * <ul> |
| * <li>Will return Node.ANY if object is null.</li> |
| * <li>Will return the enclosed Node from a FrontsNode</li> |
| * <li>Will return the object if it is a Node.</li> |
| * <li>If the object is a String |
| * <ul> |
| * <li>For <code>predicate</code> only will attempt to parse as a path</li> |
| * <li>for subject, predicate and object will call NodeFactoryExtra.parseNode() |
| * using the currently defined prefixes if the object is a String</li> |
| * </ul> |
| * </li> |
| * <li>Will create a literal representation if the parseNode() fails or for any |
| * other object type.</li> |
| * </ul> |
| * |
| * @param s The subject object |
| * @param p the predicate object |
| * @param o the object object. |
| * @return a TriplePath |
| * @deprecatd use {@link #makeTriplePaths(Object, Object, Object)} |
| */ |
| @Deprecated(since="5.0.0") |
| public TriplePath makeTriplePath(Object s, Object p, Object o) { |
| final Object po = Converters.makeNodeOrPath(p, prefixHandler.getPrefixes()); |
| if (po instanceof Path) { |
| return new TriplePath(makeNode(s), (Path) po, makeNode(o)); |
| } |
| return new TriplePath(Triple.create(makeNode(s), (Node) po, makeNode(o))); |
| } |
| |
| /** |
| * Make a collection of one or more {@code TriplePath} objects from the objects. |
| * |
| * Uses {@code Converters.makeTriplePaths} to perform the conversions using the prefixes |
| * defined in this UpdateBuilder. |
| * |
| * @param s The subject object |
| * @param p the predicate object |
| * @param o the object object. |
| * @return a collection of {@code TriplePath}s |
| */ |
| public Collection<TriplePath> makeTriplePaths(Object s, Object p, Object o) { |
| return Converters.makeTriplePaths(s, p, o, prefixHandler.getPrefixes()); |
| } |
| |
| /** |
| * Convert the object to a node. |
| * |
| * Shorthand for AbstractQueryBuilder.makeNode( o, prefixes ) |
| * |
| * @see AbstractQueryBuilder#makeNode(Object) |
| * |
| * @param o the object to convert to a node. |
| * @return the Node. |
| */ |
| public Node makeNode(Object o) { |
| return Converters.makeNode(o, prefixHandler.getPrefixes()); |
| } |
| |
| /** |
| * Convert the object to a node. |
| * |
| * Shorthand for AbstractQueryBuilder.makeVar( o ) |
| * |
| * @see Converters#makeVar(Object) |
| * |
| * @param o the object to convert to a var. |
| * @return the Var. |
| * @deprecated use {@link Converters#makeVar(Object)} |
| */ |
| @Deprecated |
| public Var makeVar(Object o) { |
| return Converters.makeVar(o); |
| } |
| |
| /** |
| * Quote a string. |
| * |
| * Shorthand for AbstractQueryBuilder.quote( s ) |
| * |
| * @see Converters#quoted(String) |
| * |
| * @deprecated Use quoted() |
| * @param s the string to quote. |
| * @return the quoted string. |
| * @deprecated use {@link Converters#quoted(String)} |
| */ |
| @Deprecated |
| public String quote(String s) { |
| return Converters.quoted(s); |
| } |
| |
| /** |
| * Converts the {@code s,p,o} triple into a list of Triples. List will contain multiple |
| * triples if {@code s} or {@code o} are collections. |
| * @param s The subject object |
| * @param p the predicate object. |
| * @param o the object object. |
| * @return A list of triples. |
| */ |
| private List<Triple> makeTriples(Object s, Object p, Object o) { |
| return Converters.makeTriples(s, p, o, prefixHandler.getPrefixes()); |
| } |
| |
| /** |
| * Add a quad to the insert statement. |
| * |
| * Arguments are converted to nodes using the makeNode() method. |
| * |
| * @see #makeNode(Object) |
| * @param g the graph |
| * @param s the subject |
| * @param p the predicate |
| * @param o the object |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsert(Object g, Object s, Object p, Object o) { |
| List<Triple> lst = makeTriples(s, p, o); |
| return lst.size()>1? addInsert(g, lst) : addInsert(g, lst.get(0)); |
| } |
| |
| /** |
| * Add a quad to the insert statement. |
| * |
| * |
| * @param quad the quad to add. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsert(Quad quad) { |
| inserts.add(new SingleQuadHolder(quad)); |
| return this; |
| } |
| |
| /** |
| * Add a triple to the insert statement. |
| * |
| * Arguments are converted to nodes using the makeNode() method. |
| * |
| * @see #makeNode(Object) |
| * @param s the subject |
| * @param p the predicate |
| * @param o the object |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsert(Object s, Object p, Object o) { |
| List<Triple> lst = makeTriples(s, p, o); |
| return lst.size()>1? addInsert(lst) : addInsert(lst.get(0)); |
| } |
| |
| /** |
| * Add a triple to the insert statement. |
| * |
| * @param t the triple to add. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsert(Triple t) { |
| inserts.add(new SingleQuadHolder(t)); |
| return this; |
| } |
| |
| /** |
| * Add a triple in a specified graph to the insert statement. |
| * |
| * The graph object is converted by a call to makeNode(). |
| * |
| * @see #makeNode(Object) |
| * @param g the graph for the triple. |
| * @param t the triple to add. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsert(Object g, Triple t) { |
| Quad q = new Quad(makeNode(g), t); |
| inserts.add(new SingleQuadHolder(q)); |
| return this; |
| } |
| |
| /** |
| * Add all the statements in the model to the insert statement. Uses |
| * Quad.defaultGraphNodeGenerated as the graph name. |
| * |
| * @param model The model to insert. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsert(Model model) { |
| inserts.add(new ModelQuadHolder(model)); |
| return this; |
| } |
| |
| /** |
| * Add all the triples in the model to the insert statement. Uses |
| * Quad.defaultGraphNodeGenerated as the graph name. |
| * |
| * @param collection The triples to insert. |
| * @return this builder for chaining. |
| * @see Quad#defaultGraphNodeGenerated |
| */ |
| public UpdateBuilder addInsert(Collection<Triple> collection) { |
| inserts.add(new CollectionQuadHolder(collection)); |
| return this; |
| } |
| |
| /** |
| * Add all the quads in the collection to the insert statement. |
| * |
| * @param collection The quads to insert. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsertQuads(Collection<Quad> collection) { |
| inserts.add(new QuadCollectionHolder(collection)); |
| return this; |
| } |
| |
| /** |
| * Add all the triples to the insert statement. Uses |
| * Quad.defaultGraphNodeGenerated as the graph name. |
| * |
| * @param iter The iterator of triples to insert. |
| * @return this builder for chaining. |
| * @see Quad#defaultGraphNodeGenerated |
| */ |
| public UpdateBuilder addInsert(Iterator<Triple> iter) { |
| inserts.add(new CollectionQuadHolder(iter)); |
| return this; |
| } |
| |
| /** |
| * Add all the statements in the model a specified graph to the insert |
| * statement. |
| * |
| * The graph object is converted by a call to makeNode(). |
| * |
| * @see #makeNode(Object) |
| * @param g the graph for the triple. |
| * @param model the model to add. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsert(Object g, Model model) { |
| inserts.add(new ModelQuadHolder(makeNode(g), model)); |
| return this; |
| } |
| |
| /** |
| * Add triples to the insert statement. |
| * |
| * @param g the name of the graph to add the triples to. |
| * @param collection The triples to insert. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsert(Object g, Collection<Triple> collection) { |
| inserts.add(new CollectionQuadHolder(makeNode(g), collection)); |
| return this; |
| } |
| |
| /** |
| * Add triples to the insert statement. |
| * |
| * @param g the name of the graph to add the triples to. |
| * @param iter The iterator of triples to insert. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsert(Object g, Iterator<Triple> iter) { |
| inserts.add(new CollectionQuadHolder(makeNode(g), iter)); |
| return this; |
| } |
| |
| /** |
| * Add the statements from the where clause in the specified query builder to |
| * the insert statement. Uses Quad.defaultGraphNodeGenerated as the graph name. |
| * |
| * @see #makeNode(Object) |
| * @see Quad#defaultGraphNodeGenerated |
| * @param queryBuilder The query builder to extract the where clause from. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsert(AbstractQueryBuilder<?> queryBuilder) { |
| inserts.add(new QBQuadHolder(queryBuilder)); |
| return this; |
| } |
| |
| /** |
| * Add the statements from the where clause in the specified query builder to |
| * the insert statements for the specified graph. |
| * |
| * The graph object is converted by a call to makeNode(). |
| * |
| * @see #makeNode(Object) |
| * @param graph the graph to add the statements to. |
| * @param queryBuilder The query builder to extract the where clause from. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addInsert(Object graph, AbstractQueryBuilder<?> queryBuilder) { |
| inserts.add(new QBQuadHolder(makeNode(graph), queryBuilder)); |
| return this; |
| } |
| |
| /** |
| * Add a quad to the delete statement. |
| * |
| * Arguments are converted to nodes using the makeNode() method. |
| * |
| * @see #makeNode(Object) |
| * @param g the graph |
| * @param s the subject |
| * @param p the predicate |
| * @param o the object |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addDelete(Object g, Object s, Object p, Object o) { |
| List<Triple> lst = makeTriples(s, p, o); |
| return lst.size()>1? addDelete(g, lst) : addDelete(g, lst.get(0)); |
| } |
| |
| /** |
| * Add a quad to the delete statement. |
| * |
| * @param quad the quad to add. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addDelete(Quad quad) { |
| deletes.add(new SingleQuadHolder(quad)); |
| return this; |
| } |
| |
| /** |
| * Add all the quads collection to the delete statement. |
| * |
| * @param collection The quads to insert. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addDeleteQuads(Collection<Quad> collection) { |
| deletes.add(new QuadCollectionHolder(collection)); |
| return this; |
| } |
| |
| /** |
| * Add a triple to the delete statement. |
| * |
| * Arguments are converted to nodes using the makeNode() method. |
| * |
| * @see #makeNode(Object) |
| * @param s the subject |
| * @param p the predicate |
| * @param o the object |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addDelete(Object s, Object p, Object o) { |
| List<Triple> lst = makeTriples(s, p, o); |
| return lst.size()>1? addDelete(lst) : addDelete(lst.get(0)); |
| } |
| |
| /** |
| * Add a triple to the delete statement. Uses Quad.defaultGraphNodeGenerated as |
| * the graph name. |
| * |
| * @param t the triple to add. |
| * @return this builder for chaining. |
| * @see Quad#defaultGraphNodeGenerated |
| */ |
| public UpdateBuilder addDelete(Triple t) { |
| deletes.add(new SingleQuadHolder(t)); |
| return this; |
| } |
| |
| /** |
| * Add a triple to the delete statement. |
| * |
| * The graph object is converted by a call to makeNode(). |
| * |
| * @see #makeNode(Object) |
| * @param g the graph for the triple. |
| * @param t the triple to add. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addDelete(Object g, Triple t) { |
| Quad q = new Quad(makeNode(g), t); |
| deletes.add(new SingleQuadHolder(q)); |
| return this; |
| } |
| |
| /** |
| * Add all the statements in the model to the delete statement. Uses |
| * Quad.defaultGraphNodeGenerated as the graph name. |
| * |
| * @param model The model to insert. |
| * @return this builder for chaining. |
| * @see Quad#defaultGraphNodeGenerated |
| */ |
| public UpdateBuilder addDelete(Model model) { |
| deletes.add(new ModelQuadHolder(model)); |
| return this; |
| } |
| |
| /** |
| * Add all triples to the delete statement. Uses Quad.defaultGraphNodeGenerated |
| * as the graph name. |
| * |
| * @param collection The collection of triples to insert. |
| * @return this builder for chaining. |
| * @see Quad#defaultGraphNodeGenerated |
| */ |
| public UpdateBuilder addDelete(Collection<Triple> collection) { |
| deletes.add(new CollectionQuadHolder(collection)); |
| return this; |
| } |
| |
| /** |
| * Add all the triples in the iterator to the delete statement. Uses |
| * Quad.defaultGraphNodeGenerated as the graph name. |
| * |
| * @param iter The iterator of triples to insert. |
| * @return this builder for chaining. |
| * @see Quad#defaultGraphNodeGenerated |
| */ |
| public UpdateBuilder addDelete(Iterator<Triple> iter) { |
| deletes.add(new CollectionQuadHolder(iter)); |
| return this; |
| } |
| |
| /** |
| * Add all the statements in the model a specified graph to the delete |
| * statement. |
| * |
| * The graph object is converted by a call to makeNode(). |
| * |
| * @see #makeNode(Object) |
| * @param g the graph for the triples. |
| * @param model the model to add. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addDelete(Object g, Model model) { |
| deletes.add(new ModelQuadHolder(makeNode(g), model)); |
| return this; |
| } |
| |
| /** |
| * Add all the statements in the model to the delete statement. |
| * |
| * @param g the graph for the triples. |
| * @param collection The collection of triples to insert. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addDelete(Object g, Collection<Triple> collection) { |
| deletes.add(new CollectionQuadHolder(makeNode(g), collection)); |
| return this; |
| } |
| |
| /** |
| * Add all the statements in the model to the delete statement. |
| * |
| * @param g the graph for the triples. |
| * @param iter The iterator of triples to insert. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addDelete(Object g, Iterator<Triple> iter) { |
| deletes.add(new CollectionQuadHolder(makeNode(g), iter)); |
| return this; |
| } |
| |
| /** |
| * Add the statements from the where clause in the specified query builder to |
| * the delete statement. Uses Quad.defaultGraphNodeGenerated as the graph name. |
| * |
| * @see #makeNode(Object) |
| * @see Quad#defaultGraphNodeGenerated |
| * @param queryBuilder The query builder to extract the where clause from. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addDelete(AbstractQueryBuilder<?> queryBuilder) { |
| deletes.add(new QBQuadHolder(queryBuilder)); |
| return this; |
| } |
| |
| /** |
| * Add the statements from the where clause in the specified query builder to |
| * the delete statements for the specified graph. |
| * |
| * The graph object is converted by a call to makeNode(). |
| * |
| * @see #makeNode(Object) |
| * @param graph the graph to add the statements to. |
| * @param queryBuilder The query builder to extract the where clause from. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder addDelete(Object graph, AbstractQueryBuilder<?> queryBuilder) { |
| deletes.add(new QBQuadHolder(makeNode(graph), queryBuilder)); |
| return this; |
| } |
| |
| /** |
| * Add the prefix to the prefix mapping. |
| * |
| * @param pfx the prefix to add. |
| * @param uri the uri for the prefix. |
| * @return this builder for chaining |
| */ |
| public UpdateBuilder addPrefix(String pfx, Resource uri) { |
| return addPrefix(pfx, uri.getURI()); |
| } |
| |
| /** |
| * Add the prefix to the prefix mapping. |
| * |
| * @param pfx the prefix to add. |
| * @param uri the uri for the prefix. |
| * @return this builder for chaining |
| */ |
| public UpdateBuilder addPrefix(String pfx, Node uri) { |
| return addPrefix(pfx, uri.getURI()); |
| } |
| |
| /** |
| * Add the prefix to the prefix mapping. |
| * |
| * @param pfx the prefix to add. |
| * @param uri the uri for the prefix. |
| * @return this builder for chaining |
| */ |
| public UpdateBuilder addPrefix(String pfx, String uri) { |
| prefixHandler.addPrefix(pfx, uri); |
| return this; |
| } |
| |
| /** |
| * Add the prefixes to the prefix mapping. |
| * |
| * @param prefixes the prefixes to add. |
| * @return this builder for chaining |
| */ |
| |
| public UpdateBuilder addPrefixes(Map<String, String> prefixes) { |
| prefixHandler.addPrefixes(prefixes); |
| return this; |
| } |
| |
| /** |
| * Add the prefixes to the prefix mapping. |
| * |
| * @param prefixes the prefix mapping to add. |
| * @return this builder for chaining |
| */ |
| |
| public UpdateBuilder addPrefixes(PrefixMapping prefixes) { |
| prefixHandler.addPrefixes(prefixes); |
| return this; |
| } |
| |
| /** |
| * Get an ExprFactory that uses the prefixes from this builder. |
| * |
| * @return the ExpressionFactory. |
| */ |
| public ExprFactory getExprFactory() { |
| return prefixHandler.getExprFactory(); |
| } |
| |
| /** |
| * Set a variable replacement. During build all instances of var in the query |
| * will be replaced with value. If value is null the replacement is cleared. |
| * |
| * @param var The variable to replace |
| * @param value The value to replace it with or null to remove the replacement. |
| */ |
| public void setVar(Var var, Node value) { |
| if (value == null) { |
| values.remove(var); |
| } else { |
| values.put(var, value); |
| } |
| } |
| |
| /** |
| * Set a variable replacement. During build all instances of var in the query |
| * will be replaced with value. If value is null the replacement is cleared. |
| * |
| * See {@link #makeVar} for conversion of the var param. See {@link #makeNode} |
| * for conversion of the value param. |
| * |
| * @param var The variable to replace. |
| * @param value The value to replace it with or null to remove the replacement. |
| */ |
| public void setVar(Object var, Object value) { |
| if (value == null) { |
| setVar(Converters.makeVar(var), null); |
| } else { |
| setVar(Converters.makeVar(var), makeNode(value)); |
| } |
| } |
| |
| private Quad check(Quad q) { |
| if (Var.isVar(q.getGraph())) |
| throw new QueryParseException("Variables not permitted in data quad", -1, -1); |
| if (Var.isVar(q.getSubject()) || Var.isVar(q.getPredicate()) || Var.isVar(q.getObject())) |
| throw new QueryParseException("Variables not permitted in data quad", -1, -1); |
| if (q.getSubject().isLiteral()) |
| throw new QueryParseException("Literals not allowed as subjects in data", -1, -1); |
| return q; |
| } |
| |
| /** |
| * Add all where attributes from the Where Handler argument. |
| * |
| * @param whereHandler The Where Handler to copy from. |
| */ |
| public UpdateBuilder addAll(WhereHandler whereHandler) { |
| whereProcessor.addAll(whereHandler); |
| return this; |
| } |
| |
| /** |
| * Add the triple path to the where clause |
| * |
| * @param t The triple path to add. |
| * @throws IllegalArgumentException If the triple path is not a valid triple |
| * path for a where clause. |
| */ |
| public UpdateBuilder addWhere(TriplePath t) throws IllegalArgumentException { |
| whereProcessor.addWhere(t); |
| return this; |
| } |
| |
| /** |
| * Add the WhereClause |
| * |
| * @param whereClause |
| * @throws IllegalArgumentException If the triple path is not a valid triple |
| * path for a where clause. |
| */ |
| public UpdateBuilder addWhere(WhereClause<?> whereClause) throws IllegalArgumentException { |
| whereProcessor.addAll(whereClause.getWhereHandler()); |
| return this; |
| } |
| |
| /** |
| * Add an optional triple to the where clause |
| * |
| * @param t The triple path to add. |
| * @return The Builder for chaining. |
| * @throws IllegalArgumentException If the triple is not a valid triple for a |
| * where clause. |
| */ |
| public UpdateBuilder addOptional(TriplePath t) throws IllegalArgumentException { |
| whereProcessor.addOptional(t); |
| return this; |
| } |
| |
| /** |
| * Add an optional triple to the where clause |
| * |
| * @param collection The collection of {@code TriplePath} path to add. |
| * @return The Builder for chaining. |
| * @throws IllegalArgumentException If the triple is not a valid triple for a |
| * where clause. |
| */ |
| public UpdateBuilder addOptional(Collection<TriplePath> collection) throws IllegalArgumentException { |
| whereProcessor.addOptional(collection); |
| return this; |
| } |
| |
| /** |
| * Add the contents of a where handler as an optional statement. |
| * |
| * @param whereHandler The where handler to use as the optional statement. |
| */ |
| public UpdateBuilder addOptional(WhereHandler whereHandler) { |
| whereProcessor.addOptional(whereHandler); |
| return this; |
| } |
| |
| /** |
| * Add an expression string as a filter. |
| * |
| * @param expression The expression string to add. |
| * @return The Builder for chaining. |
| */ |
| public UpdateBuilder addFilter(String expression) { |
| whereProcessor.addFilter(expression); |
| return this; |
| } |
| |
| /** |
| * Add a subquery to the where clause. |
| * |
| * @param subQuery The sub query to add. |
| * @return The Builder for chaining. |
| */ |
| public UpdateBuilder addSubQuery(AbstractQueryBuilder<?> subQuery) { |
| whereProcessor.addSubQuery(subQuery); |
| return this; |
| } |
| |
| /** |
| * Add a union to the where clause. |
| * |
| * @param subQuery The subquery to add as the union. |
| * @return The Builder for chaining. |
| */ |
| public UpdateBuilder addUnion(AbstractQueryBuilder<?> subQuery) { |
| whereProcessor.addUnion(subQuery); |
| return this; |
| } |
| |
| /** |
| * Add a graph to the where clause. |
| * |
| * @param graph The name of the graph. |
| * @param subQuery The where handler that defines the graph. |
| */ |
| public UpdateBuilder addGraph(Node graph, WhereHandler subQuery) { |
| whereProcessor.addGraph(graph, subQuery); |
| return this; |
| } |
| |
| /** |
| * Add a binding to the where clause. |
| * |
| * @param expr The expression to bind. |
| * @param var The variable to bind it to. |
| */ |
| public UpdateBuilder addBind(Expr expr, Var var) { |
| whereProcessor.addBind(expr, var); |
| return this; |
| } |
| |
| /** |
| * Add a binding to the where clause. |
| * |
| * @param expression The expression to bind. |
| * @param var The variable to bind it to. |
| */ |
| public UpdateBuilder addBind(String expression, Var var) { |
| whereProcessor.addBind(expression, var); |
| return this; |
| } |
| |
| /** |
| * Create a list node from a list of objects as per RDF Collections. |
| * |
| * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#collections |
| * |
| * See {@link AbstractQueryBuilder#makeNode} for conversion of the param values. |
| * <p> |
| * usage: |
| * <ul> |
| * <li>list( param1, param2, param3, ... )</li> |
| * <li>addWhere( list( param1, param2, param3, ... ), p, o )</li> |
| * <li>addOptional( list( param1, param2, param3, ... ), p, o )</li> |
| * </ul> |
| * |
| * @param objs the list of objects for the list. |
| * @return the first blank node in the list. |
| * @deprecated use makeList |
| * @see #makeList(Object...) |
| */ |
| @Deprecated(since="5.0.0") |
| public Node list(Object... objs) { |
| Node retval = NodeFactory.createBlankNode(); |
| Node lastObject = retval; |
| for (int i = 0; i < objs.length; i++) { |
| Node n = makeNode(objs[i]); |
| addWhere(new TriplePath(Triple.create(lastObject, RDF.first.asNode(), n))); |
| if (i + 1 < objs.length) { |
| Node nextObject = NodeFactory.createBlankNode(); |
| addWhere(new TriplePath(Triple.create(lastObject, RDF.rest.asNode(), nextObject))); |
| lastObject = nextObject; |
| } else { |
| addWhere(new TriplePath(Triple.create(lastObject, RDF.rest.asNode(), RDF.nil.asNode()))); |
| } |
| |
| } |
| |
| return retval; |
| } |
| |
| /** |
| * Create a list node from a list of objects as per RDF Collections. |
| * |
| * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#collections |
| * |
| * See {@link AbstractQueryBuilder#makeNode} for conversion of the param values. |
| * <p> |
| * usage: |
| * <ul> |
| * <li>list( param1, param2, param3, ... )</li> |
| * <li>addWhere( list( param1, param2, param3, ... ), p, o )</li> |
| * <li>addOptional( list( param1, param2, param3, ... ), p, o )</li> |
| * </ul> |
| * |
| * @param objs the list of objects for the list. |
| * @return the first blank node in the list. |
| */ |
| public Node makeList(Object... objs) { |
| Node retval = NodeFactory.createBlankNode(); |
| Node lastObject = retval; |
| for (int i = 0; i < objs.length; i++) { |
| Node n = makeNode(objs[i]); |
| addWhere(new TriplePath(Triple.create(lastObject, RDF.first.asNode(), n))); |
| if (i + 1 < objs.length) { |
| Node nextObject = NodeFactory.createBlankNode(); |
| addWhere(new TriplePath(Triple.create(lastObject, RDF.rest.asNode(), nextObject))); |
| lastObject = nextObject; |
| } else { |
| addWhere(new TriplePath(Triple.create(lastObject, RDF.rest.asNode(), RDF.nil.asNode()))); |
| } |
| |
| } |
| |
| return retval; |
| } |
| |
| /** |
| * Adds a triple to the where clause. |
| * |
| * @param t The triple path to add |
| * @return The Builder for chaining. |
| */ |
| public UpdateBuilder addWhere(Triple t) { |
| return addWhere(new TriplePath(t)); |
| } |
| |
| /** |
| * Adds a triple to the where clause. |
| * |
| * @param t The triple to add |
| * @return The Builder for chaining. |
| */ |
| public UpdateBuilder addWhere(FrontsTriple t) { |
| return addWhere(t.asTriple()); |
| } |
| |
| /** |
| * Adds a triple or triple path to the where clause. |
| * |
| * See {@link AbstractQueryBuilder#makeTriplePath} for conversion of the param |
| * values. |
| * |
| * @param s The subject. |
| * @param p The predicate. |
| * @param o The object. |
| * @return The Builder for chaining. |
| */ |
| public UpdateBuilder addWhere(Object s, Object p, Object o) { |
| makeTriplePaths(s, p, o).forEach(whereProcessor::addWhere); |
| return this; |
| } |
| |
| /** |
| * Adds an optional triple to the where clause. |
| * |
| * @param t The triple to add |
| * @return The Builder for chaining. |
| */ |
| public UpdateBuilder addOptional(Triple t) { |
| return addOptional(new TriplePath(t)); |
| } |
| |
| /** |
| * Adds an optional triple as to the where clause. |
| * |
| * @param t The triple to add |
| * @return The Builder for chaining. |
| */ |
| public UpdateBuilder addOptional(FrontsTriple t) { |
| return addOptional(t.asTriple()); |
| } |
| |
| /** |
| * Adds an optional triple or triple path to the where clause. |
| * |
| * See {@link AbstractQueryBuilder#makeTriplePath} for conversion of the param |
| * values. |
| * |
| * @param s The subject. |
| * @param p The predicate. |
| * @param o The object. |
| * @return The Builder for chaining. |
| */ |
| public UpdateBuilder addOptional(Object s, Object p, Object o) { |
| makeTriplePaths(s, p, o).forEach(whereProcessor::addOptional); |
| return this; |
| } |
| |
| /** |
| * Adds an optional group pattern to the where clause. |
| * |
| * @param t The select builder to add as an optional pattern |
| * @return The Builder for chaining. |
| */ |
| public UpdateBuilder addOptional(AbstractQueryBuilder<?> t) { |
| whereProcessor.addOptional(t.getWhereHandler()); |
| return this; |
| } |
| |
| /** |
| * Adds a filter to the where clause |
| * |
| * Use ExprFactory or NodeValue static or the AbstractQueryBuilder.makeExpr |
| * methods to create the expression. |
| * |
| * @see ExprFactory |
| * @see org.apache.jena.sparql.expr.NodeValue |
| * @see AbstractQueryBuilder#makeExpr(String) |
| * |
| * @param expression the expression to evaluate for the filter. |
| * @return The Builder for chaining. |
| */ |
| public UpdateBuilder addFilter(Expr expression) { |
| whereProcessor.addFilter(expression); |
| return this; |
| } |
| |
| /** |
| * Add a graph statement to the query as per |
| * http://www.w3.org/TR/2013/REC-sparql11 -query-20130321/#rGraphGraphPattern. |
| * |
| * See {@link AbstractQueryBuilder#makeNode} for conversion of the graph param. |
| * |
| * @param graph The iri or variable identifying the graph. |
| * @param subQuery The graph to add. |
| * @return This builder for chaining. |
| */ |
| public UpdateBuilder addGraph(Object graph, AbstractQueryBuilder<?> subQuery) { |
| whereProcessor.addGraph(makeNode(graph), subQuery.getWhereHandler()); |
| return this; |
| } |
| |
| /** |
| * Add a bind statement to the query * |
| * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rGraphGraphPattern. |
| * |
| * @param expression The expression to bind to the var. |
| * @param var The variable to bind to. |
| * @return This builder for chaining. |
| */ |
| public UpdateBuilder addBind(Expr expression, Object var) { |
| whereProcessor.addBind(expression, makeVar(var)); |
| return this; |
| } |
| |
| /** |
| * Add a bind statement to the query |
| * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rGraphGraphPattern. |
| * |
| * @param expression The expression to bind to the var. |
| * @param var The variable to bind to. |
| * @return This builder for chaining. |
| */ |
| public UpdateBuilder addBind(String expression, Object var) { |
| whereProcessor.addBind(expression, makeVar(var)); |
| return this; |
| } |
| |
| /** |
| * Add a minus clause to the query. |
| * |
| * https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rMinusGraphPattern |
| * |
| * @param t The select builder to add as a minus pattern |
| * @return this builder for chaining |
| */ |
| public UpdateBuilder addMinus(AbstractQueryBuilder<?> t) { |
| whereProcessor.addMinus(t); |
| return this; |
| } |
| |
| /** |
| * Specify the graph for all inserts and deletes. |
| * |
| * |
| * @see Quad#defaultGraphNodeGenerated |
| * @param iri the IRI for the graph to use. |
| * @return this builder for chaining. |
| */ |
| public UpdateBuilder with(Object iri) { |
| if (iri == null) { |
| with = null; |
| } |
| Node n = makeNode(iri); |
| if (n.isLiteral()) { |
| throw new IllegalArgumentException(String.format("IRI '%s' must not be a literal", iri)); |
| } |
| with = n; |
| return this; |
| } |
| |
| /** |
| * Create a DeleteWhere from the where clause. |
| * |
| * @return a DeleteWhere update. |
| */ |
| public UpdateDeleteWhere buildDeleteWhere() { |
| QuadAcc quadAcc = new QuadAcc(whereProcessor.getQuads().toList()); |
| return new UpdateDeleteWhere(quadAcc); |
| } |
| |
| /** |
| * Create a DeleteWhere from the where clause. |
| * |
| * @param queryBuilder the query builder to extract the where clause from. |
| * @return a DeleteWhere update. |
| */ |
| public UpdateDeleteWhere buildDeleteWhere(AbstractQueryBuilder<?> queryBuilder) { |
| QuadAcc quadAcc = new QuadAcc(new QBQuadHolder(queryBuilder).getQuads().toList()); |
| return new UpdateDeleteWhere(quadAcc); |
| } |
| |
| } |