http://git-wip-us.apache.org/repos/asf/jena/blob/2fb788d3/jena-extras/jena-querybuilder ---------------------------------------------------------------------- diff --git a/jena-extras/jena-querybuilder b/jena-extras/jena-querybuilder deleted file mode 160000 index dc4dbdb..0000000 --- a/jena-extras/jena-querybuilder +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dc4dbdb52854219a45fb9a4a8c51453e24054a08 diff --git a/jena-extras/jena-querybuilder/LICENSE b/jena-extras/jena-querybuilder/LICENSE new file mode 100644 index 0000000..e06d208 --- /dev/null +++ b/jena-extras/jena-querybuilder/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed 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. + diff --git a/jena-extras/jena-querybuilder/README.md b/jena-extras/jena-querybuilder/README.md new file mode 100644 index 0000000..6e7ab47 --- /dev/null +++ b/jena-extras/jena-querybuilder/README.md @@ -0,0 +1,49 @@ +querybuilder +============ + +Query Builder for Jena. Implementations of Ask, Construct and Select builders that allow developers to create queries without resorting to StringBuilders or similar solutions. + +Each of the builders has a series of methods to define the query. Each method returns the builder for easy chaing. The example: + +``` +SelectBuilder sb = new SelectBuilder() + .addVar( "*" ) + .addWhere( "?s", "?o", "?p" ); + +Query q = sb.build(); + +``` + +produces `SELECT * WHERE { ?s ?o ?p . }` + +Template Usage +============== + +In addition to making it easier to build valid queries the QueryBuilder has a clone method. Using this a developer can create as "Template" query and add to it as necessary. + +for example using the above query as the "template" the this code: + +``` +SelectBuilder sb2 = sb.clone(); +sb2.addPrefix( "foaf", "http://xmlns.com/foaf/0.1/" ).addWhere( ?s, RDF.type, foaf:Person) +``` + +produces `PREFIX foaf: http://xmlns.com/foaf/0.1/ SELECT * WHERE { ?s ?o ?p . ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> foaf:person . }` + +Prepared Statement Usage +======================== + +The query builders have the ability to replace variables with other values. This can be + +``` +SelectBuilder sb = new SelectBuilder() + .addVar( "*" ) + .addWhere( "?s", "?o", "?p" ); + +sb.setVar( Var.alloc( "?p" ), NodeFactory.createURI( "http://xmlns.com/foaf/0.1/Person" ) +Query q = sb.build(); + +``` + +produces `SELECT * WHERE { ?s ?o <http://xmlns.com/foaf/0.1/Person> . }` + diff --git a/jena-extras/jena-querybuilder/license-header.txt b/jena-extras/jena-querybuilder/license-header.txt new file mode 100644 index 0000000..a9ac967 --- /dev/null +++ b/jena-extras/jena-querybuilder/license-header.txt @@ -0,0 +1,14 @@ +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. \ No newline at end of file diff --git a/jena-extras/jena-querybuilder/pom.xml b/jena-extras/jena-querybuilder/pom.xml new file mode 100644 index 0000000..da311b5 --- /dev/null +++ b/jena-extras/jena-querybuilder/pom.xml @@ -0,0 +1,48 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>jena-querybuilder</artifactId> + <build> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.7</source> + <target>1.7</target> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>org.apache.jena</groupId> + <artifactId>apache-jena-libs</artifactId> + <type>pom</type> + </dependency> + <dependency> + <groupId>org.xenei</groupId> + <artifactId>junit-contracts</artifactId> + </dependency> + </dependencies> + <name>Apache Jena Query Builder- jena-querybulder</name> + <inceptionYear>2014</inceptionYear> + <organization> + <name>The Apache Software Foundation</name> + <url>http://www.apache.org/</url> + </organization> + <properties> + + </properties> + <scm> + <!-- <url>https://svn.apache.org/repos/asf/jena/Experimental/jena-common/</url> + <connection>scm:svn:https://svn.apache.org/repos/asf/jena/Experimental/jena-common/</connection> + <developerConnection>scm:svn:https://svn.apache.org/repos/asf/jena/Experimental/jena-common/</developerConnection> + --> + </scm> + <parent> + <groupId>org.apache.jena</groupId> + <artifactId>jena-extras</artifactId> + <relativePath>..</relativePath> + <version>2.12.2-SNAPSHOT</version> + </parent> + <description>A utility package to simplify the building of ARQ queries in code. Provides both a simple builder interface for queries as well as simple prepared statement processing.</description> +</project> \ No newline at end of file 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 new file mode 100644 index 0000000..baea059 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AbstractQueryBuilder.java @@ -0,0 +1,362 @@ +/* + * 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.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +import org.apache.jena.arq.querybuilder.clauses.ConstructClause; +import org.apache.jena.arq.querybuilder.clauses.DatasetClause; +import org.apache.jena.arq.querybuilder.clauses.PrologClause; +import org.apache.jena.arq.querybuilder.clauses.SelectClause; +import org.apache.jena.arq.querybuilder.clauses.SolutionModifierClause; +import org.apache.jena.arq.querybuilder.clauses.WhereClause; +import org.apache.jena.arq.querybuilder.handlers.ConstructHandler; +import org.apache.jena.arq.querybuilder.handlers.DatasetHandler; +import org.apache.jena.arq.querybuilder.handlers.Handler; +import org.apache.jena.arq.querybuilder.handlers.PrologHandler; +import org.apache.jena.arq.querybuilder.handlers.SelectHandler; +import org.apache.jena.arq.querybuilder.handlers.SolutionModifierHandler; +import org.apache.jena.arq.querybuilder.handlers.WhereHandler; +import org.apache.jena.riot.RiotException; +import org.apache.jena.riot.system.PrefixMapFactory; + +import com.hp.hpl.jena.graph.FrontsNode; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.NodeFactory; +import com.hp.hpl.jena.graph.impl.LiteralLabelFactory; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.sparql.ARQInternalErrorException; +import com.hp.hpl.jena.sparql.core.Var; +import com.hp.hpl.jena.sparql.expr.ExprVar; +import com.hp.hpl.jena.sparql.util.NodeFactoryExtra; + +/** + * Base class for all QueryBuilders. + * + * @param <T> + * The derived class type. Used for return types. + */ +public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> + implements Cloneable, PrologClause<T> { + + // all queries have prologs + protected PrologHandler prologHandler; + // the query this builder is building + protected Query query; + // a map of vars to nodes for replacement during build. + private Map<Var, Node> values; + + /** + * Make a Node from an object. + * <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>Will call NodeFactoryExtra.parseNode() using the currently defined + * prefixes if the object is a String</li> + * <li>Will create a literal representation if the parseNode() fails or for + * any other object type.</li> + * </ul> + * + * @param o + * The object to convert. (may be null) + * @return The Node value. + */ + public Node makeNode(Object o) { + if (o == null) { + return Node.ANY; + } + if (o instanceof FrontsNode) { + return ((FrontsNode) o).asNode(); + } + + if (o instanceof Node) { + return (Node) o; + } + if (o instanceof String) { + try { + return NodeFactoryExtra.parseNode((String) o, PrefixMapFactory + .createForInput(query.getPrefixMapping())); + } catch (RiotException e) { + // expected in some cases -- do nothing + } + + } + return NodeFactory.createLiteral(LiteralLabelFactory.create(o)); + } + + /** + * Make a Var from an object. + * <ul> + * <li>Will return Var.ANON if object is null.</li> + * <li>Will return null if the object is "*" or Node_RuleVariable.WILD</li> + * <li>Will return the object if it is a Var</li> + * <li>Will return resolve FrontsNode to Node and then resolve to Var</li> + * <li>Will return resolve Node if the Node implements Node_Variable, + * otherwise throws an NotAVariableException (instance of + * ARQInternalErrorException)</li> + * <li>Will return ?x if object is "?x"</li> + * <li>Will return ?x if object is "x"</li> + * <li>Will return the enclosed Var of a ExprVar</li> + * <li>For all other objects will return the "?" prefixed to the toString() + * value.</li> + * </ul> + * + * @param o + * The object to convert. + * @return the Var value. + * @throws ARQInternalErrorException + */ + public Var makeVar(Object o) throws ARQInternalErrorException { + if (o == null) { + return Var.ANON; + } + if (o instanceof Var) { + return (Var) o; + } + Var retval = null; + if (o instanceof FrontsNode) { + retval = Var.alloc(((FrontsNode) o).asNode()); + } else if (o instanceof Node) { + retval = Var.alloc((Node) o); + } else if (o instanceof ExprVar) { + retval = Var.alloc((ExprVar) o); + } else { + retval = Var.alloc(Var.canonical(o.toString())); + } + if ("*".equals(Var.canonical(retval.toString()))) { + return null; + } + return retval; + } + + /** + * Create a new query builder. + */ + protected AbstractQueryBuilder() { + query = new Query(); + prologHandler = new PrologHandler(query); + values = new HashMap<Var, Node>(); + } + + /** + * 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(makeVar(var), null); + } else { + setVar(makeVar(var), makeNode(value)); + } + } + + @Override + public PrologHandler getPrologHandler() { + return prologHandler; + } + + @Override + public T addPrefix(String pfx, Resource uri) { + return addPrefix(pfx, uri.getURI()); + } + + @Override + public T addPrefix(String pfx, Node uri) { + return addPrefix(pfx, uri.getURI()); + } + + @SuppressWarnings("unchecked") + @Override + public T addPrefix(String pfx, String uri) { + prologHandler.addPrefix(pfx, uri); + return (T) this; + } + + @SuppressWarnings("unchecked") + @Override + public T addPrefixes(Map<String, String> prefixes) { + prologHandler.addPrefixes(prefixes); + return (T) this; + } + + @SuppressWarnings("unchecked") + @Override + public T setBase(String base) { + prologHandler.setBase(base); + return (T) this; + } + + @SuppressWarnings("unchecked") + @Override + public T setBase(Object base) { + setBase(makeNode(base).getURI()); + return (T) this; + } + + @Override + public String toString() { + return buildString(); + } + + /** + * Build the query as a string. + * + * @return the string representation of the query. + */ + public final String buildString() { + return build().toString(); + } + + /** + * Build the query. Performs the var replacements as specified by + * setVar(var,node) calls. + * + * @return The query. + */ + public final Query build() { + Query q = new Query(); + try { + Field f = Query.class.getDeclaredField("queryType"); + f.setAccessible(true); + f.set(q, query.getQueryType()); + } catch (NoSuchFieldException e) { + throw new IllegalStateException(e.getMessage(), e); + } catch (SecurityException e) { + throw new IllegalStateException(e.getMessage(), e); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e.getMessage(), e); + } + Stack<Handler> handlerStack = new Stack<Handler>(); + PrologHandler ph = new PrologHandler(q); + handlerStack.push(ph); + ph.addAll(prologHandler); + ph.setVars(values); + if (this instanceof SelectClause) { + SelectHandler sh = new SelectHandler(q); + sh.addAll(((SelectClause<?>) this).getSelectHandler()); + sh.setVars(values); + handlerStack.push(sh); + } + if (this instanceof ConstructClause) { + ConstructHandler ch = new ConstructHandler(q); + ch.addAll(((ConstructClause<?>) this).getConstructHandler()); + ch.setVars(values); + handlerStack.push(ch); + } + if (this instanceof DatasetClause) { + DatasetHandler dh = new DatasetHandler(q); + dh.addAll(((DatasetClause<?>) this).getDatasetHandler()); + dh.setVars(values); + handlerStack.push(dh); + } + if (this instanceof SolutionModifierClause) { + SolutionModifierHandler smh = new SolutionModifierHandler(q); + smh.addAll(((SolutionModifierClause<?>) this) + .getSolutionModifierHandler()); + smh.setVars(values); + handlerStack.push(smh); + } + if (this instanceof WhereClause) { + WhereHandler wh = new WhereHandler(q); + wh.addAll(((WhereClause<?>) this).getWhereHandler()); + wh.setVars(values); + handlerStack.push(wh); + } + + while (!handlerStack.isEmpty()) { + handlerStack.pop().build(); + } + + return q; + } + + /** + * Close the query. + * + * This can be used when the query would not normally parse as is required + * by the Query.clone() method. + * + * @param q2 + * The query to clone + * @return A clone of the q2 param. + */ + public static Query clone(Query q2) { + Query retval = new Query(); + new PrologHandler(retval).addAll(new PrologHandler(q2)); + new ConstructHandler(retval).addAll(new ConstructHandler(q2)); + new DatasetHandler(retval).addAll(new DatasetHandler(q2)); + new SolutionModifierHandler(retval).addAll(new SolutionModifierHandler( + q2)); + new WhereHandler(retval).addAll(new WhereHandler(q2)); + new SelectHandler(retval).addAll(new SelectHandler(q2)); + return retval; + } + + /** + * Rewrite a query replacing variables as specified in the values map. + * + * @param q2 + * The query to rewrite + * @param values + * a Mapping of var to node for replacement. + * @return The new query with the specified vars replaced. + */ + public static Query rewrite(Query q2, Map<Var, Node> values) { + new PrologHandler(q2).setVars(values); + new ConstructHandler(q2).setVars(values); + new DatasetHandler(q2).setVars(values); + new SolutionModifierHandler(q2).setVars(values); + new WhereHandler(q2).setVars(values); + new SelectHandler(q2).setVars(values); + return q2; + } +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AskBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AskBuilder.java new file mode 100644 index 0000000..edb6885 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/AskBuilder.java @@ -0,0 +1,198 @@ +/* + * 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 org.apache.jena.arq.querybuilder.clauses.DatasetClause; +import org.apache.jena.arq.querybuilder.clauses.SolutionModifierClause; +import org.apache.jena.arq.querybuilder.clauses.WhereClause; +import org.apache.jena.arq.querybuilder.handlers.DatasetHandler; +import org.apache.jena.arq.querybuilder.handlers.SolutionModifierHandler; +import org.apache.jena.arq.querybuilder.handlers.WhereHandler; + +import com.hp.hpl.jena.graph.FrontsTriple; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.sparql.lang.sparql_11.ParseException; + +/** + * Build an ASK query. + * + */ +public class AskBuilder extends AbstractQueryBuilder<AskBuilder> implements + DatasetClause<AskBuilder>, WhereClause<AskBuilder>, + SolutionModifierClause<AskBuilder> { + // the dataset handler + private final DatasetHandler datasetHandler; + // the where handler. + private final WhereHandler whereHandler; + // the solution modifier handler. + private final SolutionModifierHandler solutionModifier; + + /** + * The constructor + */ + public AskBuilder() { + super(); + query.setQueryAskType(); + datasetHandler = new DatasetHandler(query); + whereHandler = new WhereHandler(query); + solutionModifier = new SolutionModifierHandler(query); + } + + @Override + public DatasetHandler getDatasetHandler() { + return datasetHandler; + } + + @Override + public WhereHandler getWhereHandler() { + return whereHandler; + } + + @Override + public AskBuilder clone() { + AskBuilder qb = new AskBuilder(); + qb.prologHandler.addAll(prologHandler); + qb.datasetHandler.addAll(datasetHandler); + qb.solutionModifier.addAll(solutionModifier); + return qb; + } + + @Override + public AskBuilder fromNamed(String graphName) { + datasetHandler.fromNamed(graphName); + return this; + } + + @Override + public AskBuilder fromNamed(Collection<String> graphNames) { + datasetHandler.fromNamed(graphNames); + return this; + } + + @Override + public AskBuilder from(String graphName) { + datasetHandler.from(graphName); + return this; + } + + @Override + public AskBuilder from(Collection<String> graphName) { + datasetHandler.from(graphName); + return this; + } + + @Override + public AskBuilder addWhere(Triple t) { + whereHandler.addWhere(t); + return this; + } + + @Override + public AskBuilder addWhere(FrontsTriple t) { + whereHandler.addWhere(t.asTriple()); + return this; + } + + @Override + public AskBuilder addWhere(Object s, Object p, Object o) { + addWhere(new Triple(makeNode(s), makeNode(p), makeNode(o))); + return this; + } + + @Override + public AskBuilder addOptional(Triple t) { + whereHandler.addOptional(t); + return this; + } + + @Override + public AskBuilder addOptional(FrontsTriple t) { + whereHandler.addOptional(t.asTriple()); + return this; + } + + @Override + public AskBuilder addOptional(Object s, Object p, Object o) { + addOptional(new Triple(makeNode(s), makeNode(p), makeNode(o))); + return this; + } + + @Override + public AskBuilder addFilter(String s) throws ParseException { + whereHandler.addFilter(s); + return this; + } + + @Override + public AskBuilder addSubQuery(SelectBuilder subQuery) { + prologHandler.addAll(subQuery.getPrologHandler()); + whereHandler.addSubQuery(subQuery); + return this; + } + + @Override + public AskBuilder addUnion(SelectBuilder subQuery) { + whereHandler.addUnion(subQuery); + return this; + } + + @Override + public AskBuilder addGraph(Object graph, SelectBuilder subQuery) { + prologHandler.addAll(subQuery.getPrologHandler()); + whereHandler.addGraph(makeNode(graph), subQuery.getWhereHandler()); + return this; + } + + @Override + public AskBuilder addOrderBy(String orderBy) { + solutionModifier.addOrderBy(orderBy); + return this; + } + + @Override + public AskBuilder addGroupBy(String groupBy) { + solutionModifier.addGroupBy(groupBy); + return this; + } + + @Override + public AskBuilder addHaving(String having) throws ParseException { + solutionModifier.addHaving(having); + return this; + } + + @Override + public AskBuilder setLimit(int limit) { + solutionModifier.setLimit(limit); + return this; + } + + @Override + public AskBuilder setOffset(int offset) { + solutionModifier.setOffset(offset); + return this; + } + + @Override + public SolutionModifierHandler getSolutionModifierHandler() { + return solutionModifier; + } + +} \ No newline at end of file diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ConstructBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ConstructBuilder.java new file mode 100644 index 0000000..eddc764 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/ConstructBuilder.java @@ -0,0 +1,244 @@ +/* + * 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 org.apache.jena.arq.querybuilder.clauses.ConstructClause; +import org.apache.jena.arq.querybuilder.clauses.DatasetClause; +import org.apache.jena.arq.querybuilder.clauses.SolutionModifierClause; +import org.apache.jena.arq.querybuilder.clauses.WhereClause; +import org.apache.jena.arq.querybuilder.handlers.ConstructHandler; +import org.apache.jena.arq.querybuilder.handlers.DatasetHandler; +import org.apache.jena.arq.querybuilder.handlers.SolutionModifierHandler; +import org.apache.jena.arq.querybuilder.handlers.WhereHandler; + +import com.hp.hpl.jena.graph.FrontsTriple; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.sparql.lang.sparql_11.ParseException; + +/** + * Build an Construct query. + * + */ +public class ConstructBuilder extends AbstractQueryBuilder<ConstructBuilder> + implements DatasetClause<ConstructBuilder>, + WhereClause<ConstructBuilder>, + SolutionModifierClause<ConstructBuilder>, + ConstructClause<ConstructBuilder> { + + // the handlers used by this builder + private final DatasetHandler datasetHandler; + private final WhereHandler whereHandler; + private final SolutionModifierHandler solutionModifier; + private final ConstructHandler constructHandler; + + /** + * Constructor + */ + public ConstructBuilder() { + super(); + query.setQueryConstructType(); + datasetHandler = new DatasetHandler(query); + whereHandler = new WhereHandler(query); + solutionModifier = new SolutionModifierHandler(query); + constructHandler = new ConstructHandler(query); + } + + @Override + public DatasetHandler getDatasetHandler() { + return datasetHandler; + } + + @Override + public WhereHandler getWhereHandler() { + return whereHandler; + } + + @Override + public ConstructHandler getConstructHandler() { + return constructHandler; + } + + @Override + public SolutionModifierHandler getSolutionModifierHandler() { + return solutionModifier; + } + + @Override + public ConstructBuilder clone() { + ConstructBuilder qb = new ConstructBuilder(); + qb.prologHandler.addAll(prologHandler); + qb.datasetHandler.addAll(datasetHandler); + qb.whereHandler.addAll(whereHandler); + qb.solutionModifier.addAll(solutionModifier); + qb.constructHandler.addAll(constructHandler); + return qb; + } + + @Override + public ConstructBuilder fromNamed(String graphName) { + datasetHandler.fromNamed(graphName); + return this; + } + + @Override + public ConstructBuilder fromNamed(Collection<String> graphNames) { + datasetHandler.fromNamed(graphNames); + return this; + } + + @Override + public ConstructBuilder from(String graphName) { + datasetHandler.from(graphName); + return this; + } + + @Override + public ConstructBuilder from(Collection<String> graphName) { + datasetHandler.from(graphName); + return this; + } + + @Override + public ConstructBuilder addOrderBy(String orderBy) { + solutionModifier.addOrderBy(orderBy); + return this; + } + + @Override + public ConstructBuilder addGroupBy(String groupBy) { + solutionModifier.addGroupBy(groupBy); + return this; + } + + @Override + public ConstructBuilder addHaving(String having) throws ParseException { + solutionModifier.addHaving(having); + return this; + } + + @Override + public ConstructBuilder setLimit(int limit) { + solutionModifier.setLimit(limit); + return this; + } + + @Override + public ConstructBuilder setOffset(int offset) { + solutionModifier.setOffset(offset); + return this; + } + + // convert a node to a string + private static String toString(Node node) { + if (node.isBlank()) { + return node.getBlankNodeLabel(); + } + if (node.isLiteral()) { + return node.toString(); + } + if (node.isURI()) { + return String.format("<%s>", node.getURI()); + } + if (node.isVariable()) { + return String.format("?%s", node.getName()); + } + return node.toString(); + } + + @Override + public ConstructBuilder addWhere(Triple t) { + whereHandler.addWhere(t); + return this; + } + + @Override + public ConstructBuilder addWhere(FrontsTriple t) { + whereHandler.addWhere(t.asTriple()); + return this; + } + + @Override + public ConstructBuilder addWhere(Object s, Object p, Object o) { + addWhere(new Triple(makeNode(s), makeNode(p), makeNode(o))); + return this; + } + + @Override + public ConstructBuilder addOptional(Triple t) { + whereHandler.addOptional(t); + return this; + } + + @Override + public ConstructBuilder addOptional(FrontsTriple t) { + whereHandler.addOptional(t.asTriple()); + return this; + } + + @Override + public ConstructBuilder addOptional(Object s, Object p, Object o) { + addOptional(new Triple(makeNode(s), makeNode(p), makeNode(o))); + return this; + } + + @Override + public ConstructBuilder addFilter(String s) throws ParseException { + whereHandler.addFilter(s); + return this; + } + + @Override + public ConstructBuilder addSubQuery(SelectBuilder subQuery) { + prologHandler.addAll(subQuery.prologHandler); + whereHandler.addSubQuery(subQuery); + return this; + } + + @Override + public ConstructBuilder addUnion(SelectBuilder subQuery) { + whereHandler.addUnion(subQuery); + return this; + } + + @Override + public ConstructBuilder addGraph(Object graph, SelectBuilder subQuery) { + prologHandler.addAll(subQuery.prologHandler); + whereHandler.addGraph(makeNode(graph), subQuery.getWhereHandler()); + return this; + } + + @Override + public ConstructBuilder addConstruct(Triple t) { + constructHandler.addConstruct(t); + return this; + } + + @Override + public ConstructBuilder addConstruct(FrontsTriple t) { + return addConstruct(t.asTriple()); + } + + @Override + public ConstructBuilder addConstruct(Object s, Object p, Object o) { + return addConstruct(new Triple(makeNode(s), makeNode(p), makeNode(o))); + } + +} \ No newline at end of file diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/SelectBuilder.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/SelectBuilder.java new file mode 100644 index 0000000..30b5ab0 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/SelectBuilder.java @@ -0,0 +1,281 @@ +/* + * 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 org.apache.jena.arq.querybuilder.clauses.DatasetClause; +import org.apache.jena.arq.querybuilder.clauses.SelectClause; +import org.apache.jena.arq.querybuilder.clauses.SolutionModifierClause; +import org.apache.jena.arq.querybuilder.clauses.WhereClause; +import org.apache.jena.arq.querybuilder.handlers.DatasetHandler; +import org.apache.jena.arq.querybuilder.handlers.SelectHandler; +import org.apache.jena.arq.querybuilder.handlers.SolutionModifierHandler; +import org.apache.jena.arq.querybuilder.handlers.WhereHandler; + +import com.hp.hpl.jena.graph.FrontsNode; +import com.hp.hpl.jena.graph.FrontsTriple; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.sparql.core.Var; +import com.hp.hpl.jena.sparql.lang.sparql_11.ParseException; + +/** + * Build a select query. + * + */ +public class SelectBuilder extends AbstractQueryBuilder<SelectBuilder> + implements DatasetClause<SelectBuilder>, WhereClause<SelectBuilder>, + SolutionModifierClause<SelectBuilder>, SelectClause<SelectBuilder> { + + // the handlers. + private DatasetHandler datasetHandler; + private WhereHandler whereHandler; + private SolutionModifierHandler solutionModifier; + private SelectHandler selectHandler; + + /** + * Constructor. + */ + public SelectBuilder() { + super(); + query.setQuerySelectType(); + datasetHandler = new DatasetHandler(query); + whereHandler = new WhereHandler(query); + solutionModifier = new SolutionModifierHandler(query); + selectHandler = new SelectHandler(query); + } + + @Override + public DatasetHandler getDatasetHandler() { + return datasetHandler; + } + + @Override + public WhereHandler getWhereHandler() { + return whereHandler; + } + + @Override + public SelectBuilder clone() { + SelectBuilder qb = new SelectBuilder(); + qb.prologHandler.addAll(prologHandler); + qb.datasetHandler.addAll(datasetHandler); + qb.whereHandler.addAll(whereHandler); + qb.solutionModifier.addAll(solutionModifier); + qb.selectHandler.addAll(selectHandler); + + return qb; + } + + @Override + public SelectBuilder setDistinct(boolean state) { + selectHandler.setDistinct(state); + return this; + } + + @Override + public SelectBuilder setReduced(boolean state) { + selectHandler.setReduced(state); + return this; + } + + @Override + public SelectBuilder addVar(Object var) { + selectHandler.addVar(makeVar(var)); + return this; + } + + @Override + public List<Var> getVars() { + return selectHandler.getVars(); + } + + @Override + public SelectBuilder fromNamed(String graphName) { + datasetHandler.fromNamed(graphName); + return this; + } + + @Override + public SelectBuilder fromNamed(Collection<String> graphNames) { + datasetHandler.fromNamed(graphNames); + return this; + } + + @Override + public SelectBuilder from(String graphName) { + datasetHandler.from(graphName); + return this; + } + + @Override + public SelectBuilder from(Collection<String> graphName) { + datasetHandler.from(graphName); + return this; + } + + @Override + public SelectBuilder addOrderBy(String orderBy) { + solutionModifier.addOrderBy(orderBy); + return this; + } + + @Override + public SelectBuilder addGroupBy(String groupBy) { + solutionModifier.addGroupBy(groupBy); + return this; + } + + @Override + public SolutionModifierHandler getSolutionModifierHandler() { + return solutionModifier; + } + + @Override + public SelectBuilder addHaving(String having) throws ParseException { + solutionModifier.addHaving(having); + return this; + } + + @Override + public SelectBuilder setLimit(int limit) { + solutionModifier.setLimit(limit); + return this; + } + + @Override + public SelectBuilder setOffset(int offset) { + solutionModifier.setOffset(offset); + return this; + } + + /** + * Convert a node to a string. + * If the node is a literal return the literal value. + * If the node is a URI return the URI enclosed with < and > + * If the node is a variable return the name preceeded by '?' + * @param node The node to convert. + * @return A string representation of the node. + */ + private static String toString(Node node) { + if (node.isBlank()) { + return node.getBlankNodeLabel(); + } + if (node.isLiteral()) { + return node.toString(); + } + if (node.isURI()) { + return String.format("<%s>", node.getURI()); + } + if (node.isVariable()) { + return String.format("?%s", node.getName()); + } + return node.toString(); + } + + /** + * Convert the object to a string. + * If the object is a node or fronts a node then + * <ul> + * <li>If the node is a literal return the literal value.</li> + * <li>If the node is a URI return the URI enclosed with < and ></li> + * <li>If the node is a variable return the name preceeded by '?'</li> + * </ul> + * otherwise return the toString() method of the object. + * @param o the Object to convert. + * @return The string representation of the object. + */ + public static String makeString(Object o) { + if (o instanceof FrontsNode) { + return toString(((FrontsNode) o).asNode()); + } + if (o instanceof Node) { + return toString((Node) o); + } + return o.toString(); + } + + @Override + public SelectBuilder addWhere(Triple t) { + whereHandler.addWhere(t); + return this; + } + + @Override + public SelectBuilder addWhere(FrontsTriple t) { + whereHandler.addWhere(t.asTriple()); + return this; + } + + @Override + public SelectBuilder addWhere(Object s, Object p, Object o) { + addWhere(new Triple(makeNode(s), makeNode(p), makeNode(o))); + return this; + } + + @Override + public SelectBuilder addOptional(Triple t) { + whereHandler.addOptional(t); + return this; + } + + @Override + public SelectBuilder addOptional(FrontsTriple t) { + whereHandler.addOptional(t.asTriple()); + return this; + } + + @Override + public SelectBuilder addOptional(Object s, Object p, Object o) { + addOptional(new Triple(makeNode(s), makeNode(p), makeNode(o))); + return this; + } + + @Override + public SelectBuilder addFilter(String s) throws ParseException { + whereHandler.addFilter(s); + return this; + } + + @Override + public SelectBuilder addSubQuery(SelectBuilder subQuery) { + prologHandler.addAll(subQuery.prologHandler); + whereHandler.addSubQuery(subQuery); + return this; + } + + @Override + public SelectBuilder addUnion(SelectBuilder subQuery) { + whereHandler.addUnion(subQuery); + return this; + } + + @Override + public SelectBuilder addGraph(Object graph, SelectBuilder subQuery) { + prologHandler.addAll(subQuery.prologHandler); + whereHandler.addGraph(makeNode(graph), subQuery.whereHandler); + return this; + } + + @Override + public SelectHandler getSelectHandler() { + return selectHandler; + } + +} \ No newline at end of file diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/ConstructClause.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/ConstructClause.java new file mode 100644 index 0000000..285fc92 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/ConstructClause.java @@ -0,0 +1,74 @@ +/* + * 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.clauses; + +import org.apache.jena.arq.querybuilder.AbstractQueryBuilder; +import org.apache.jena.arq.querybuilder.handlers.ConstructHandler; + +import com.hp.hpl.jena.graph.FrontsTriple; +import com.hp.hpl.jena.graph.Triple; + +/** + * Interface that defines the ConstructClause as per + * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rConstructTemplate + * + * @param <T> + * The Builder type that the clause is part of. + */ +public interface ConstructClause<T extends AbstractQueryBuilder<T>> { + + /** + * Add a construct triple. + * + * @param t + * The triple to add. + * @return The builder for chaining. + */ + public T addConstruct(Triple t); + + /** + * Add a construct triple. + * + * @param t + * The triple to add. + * @return The builder for chaining. + */ + public T addConstruct(FrontsTriple t); + + /** + * Add a construct triple. + * + * See {@link AbstractQueryBuilder#makeNode} for conversion of the param values. + * + * @param s + * The subject of the triple, + * @param p + * The predicate of the triple. + * @param o + * The object of the triple. + * @return the builder for chaining. + */ + public T addConstruct(Object s, Object p, Object o); + + /** + * Get the Construct handler for this construct clause. + * @return the construct handler used by this builder. + */ + public ConstructHandler getConstructHandler(); + +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/DatasetClause.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/DatasetClause.java new file mode 100644 index 0000000..faa51c0 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/DatasetClause.java @@ -0,0 +1,75 @@ +/* + * 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.clauses; + +import java.util.Collection; + +import org.apache.jena.arq.querybuilder.AbstractQueryBuilder; +import org.apache.jena.arq.querybuilder.handlers.DatasetHandler; + +/** + * Interface that defines the DatasetClause as per + * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rDatasetClause + * + * @param <T> + * The Builder type that the clause is part of. + */ +public interface DatasetClause<T extends AbstractQueryBuilder<T>> { + /** + * Add the "FROM NAMED" graph name. + * + * @param graphName + * the graph name to add. + * @return The builder for chaining. + */ + public T fromNamed(String graphName); + + /** + * Add several "FROM NAMED" graph names. + * + * @param graphNames + * the collection graph names to add. + * @return The builder for chaining. + */ + public T fromNamed(Collection<String> graphNames); + + /** + * Add the "FROM" graph name. + * + * @param graphName + * the graph name to add. + * @return The builder for chaining. + */ + public T from(String graphName); + + /** + * Add several "FROM" graph names. + * + * @param graphName + * the collection graph names to add. + * @return The builder for chaining. + */ + public T from(Collection<String> graphName); + + /** + * Get the Dataset handler for this clause. + * @return The DatasetHandler this clause is using. + */ + public DatasetHandler getDatasetHandler(); + +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/PrologClause.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/PrologClause.java new file mode 100644 index 0000000..8f69598 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/PrologClause.java @@ -0,0 +1,105 @@ +/* + * 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.clauses; + +import java.util.Map; + +import org.apache.jena.arq.querybuilder.AbstractQueryBuilder; +import org.apache.jena.arq.querybuilder.handlers.PrologHandler; + +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.rdf.model.Resource; + +/** + * Interface that defines the PrologClause as per + * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rPrologue + * + * @param <T> + * The Builder type that the clause is part of. + */ +public interface PrologClause<T extends AbstractQueryBuilder<T>> { + /** + * Get the prolog handler for this clause. + * @return The PrologHandler this clause is using. + */ + public PrologHandler getPrologHandler(); + + /** + * Add a prefix. + * + * @param pfx + * The prefix. + * @param uri + * The URI for the prefix + * @return The builder for chaining. + */ + public T addPrefix(String pfx, Resource uri); + + /** + * Add a prefix. + * + * @param pfx + * The prefix. + * @param uri + * The URI for the prefix + * @return The builder for chaining. + */ + public T addPrefix(String pfx, Node uri); + + /** + * Add a prefix. + * + * @param pfx + * The prefix. + * @param uri + * The URI for the prefix + * @return The builder for chaining. + */ + public T addPrefix(String pfx, String uri); + + /** + * Add a prefix. + * + * @param prefixes + * A mapping of prefix to URI to add. + * @return The builder for chaining. + */ + public T addPrefixes(Map<String, String> prefixes); + + /** + * Set the base URI. + * + * See {@link AbstractQueryBuilder#makeNode} for conversion of the uri param. The resulting Node + * must be a URI. + * + * @param uri + * The base URI to use. + * @return The builder for chaining. + */ + public T setBase(Object uri); + + /** + * Set the base URI. + * + * @param uri + * The base URI to use. + * @return The builder for chaining. + */ + public T setBase(String uri); + +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/SelectClause.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/SelectClause.java new file mode 100644 index 0000000..2d29010 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/SelectClause.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jena.arq.querybuilder.clauses; + +import java.util.List; +import org.apache.jena.arq.querybuilder.AbstractQueryBuilder; +import org.apache.jena.arq.querybuilder.handlers.SelectHandler; + +import com.hp.hpl.jena.sparql.core.Var; + +/** + * Interface that defines the SelectClause as per + * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rSelectClause + * + * @param <T> + * The Builder type that the clause is part of. + */ +public interface SelectClause<T extends AbstractQueryBuilder<T>> { + /** + * Get the select handler for this clause + * @return The SelectHandler that the clause is using + */ + public SelectHandler getSelectHandler(); + + /** + * Set set the distinct flag. + * + * Setting the select distinct will unset reduced if it was set. + * + * @param state + * if true results will be distinct. + * @return The builder for chaining. + */ + public T setDistinct(boolean state); + + /** + * Set set the reduced flag. + * + * Setting the select reduced will unset distinct if it was set. + * + * @param state + * if true results will be reduced. + * @return The builder for chaining. + */ + public T setReduced(boolean state); + + /** + * Add a variable to the select statement. + * + * A variable may only be added once. Attempting to add the same variable + * multiple times will be silently ignored. + * + * @param var + * The variable to add. + * @return The builder for chaining. + */ + public T addVar(Object var); + + /** + * @return A list of all the variables that have been added. + */ + public List<Var> getVars(); + +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierClause.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierClause.java new file mode 100644 index 0000000..3be18a0 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/SolutionModifierClause.java @@ -0,0 +1,89 @@ +/* + * 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.clauses; + +import org.apache.jena.arq.querybuilder.AbstractQueryBuilder; +import org.apache.jena.arq.querybuilder.handlers.SolutionModifierHandler; + +import com.hp.hpl.jena.sparql.lang.sparql_11.ParseException; + +/** + * Interface that defines the SolutionClause as per + * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rSolutionModifier + * + * @param <T> + * The Builder type that the clause is part of. + */ +public interface SolutionModifierClause<T extends AbstractQueryBuilder<T>> { + + /** + * Add an order by + * + * @param orderBy + * The variable name to order by. + * @return The builder for chaining. + */ + public T addOrderBy(String orderBy); + + /** + * Add a group by + * + * @param groupBy + * The variable name to group by. + * @return The builder for chaining. + */ + public T addGroupBy(String groupBy); + + /** + * Add a having expression. + * + * @param expression + * Expression to evaluate for the having. + * @return The builder for chaining. + */ + public T addHaving(String expression) throws ParseException; + + /** + * Set the limit. + * + * Setting the limit to 0 (zero) sets no limit. + * + * @param limit + * the maximum number of results to return. + * @return The builder for chaining. + */ + public T setLimit(int limit); + + /** + * Set the offset. + * + * Setting the offset to 0 (zero) sets no offset. + * + * @param offset + * the number of results to skip before returning results.. + * @return The builder for chaining. + */ + public T setOffset(int offset); + + /** + * Get the Solution modifier for this clause. + * @return The SolutionModifierHandler the clause is using. + */ + public SolutionModifierHandler getSolutionModifierHandler(); + +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/WhereClause.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/WhereClause.java new file mode 100644 index 0000000..9f92941 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/WhereClause.java @@ -0,0 +1,153 @@ +/* + * 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.clauses; + +import org.apache.jena.arq.querybuilder.AbstractQueryBuilder; +import org.apache.jena.arq.querybuilder.SelectBuilder; +import org.apache.jena.arq.querybuilder.handlers.WhereHandler; + +import com.hp.hpl.jena.graph.FrontsTriple; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.sparql.lang.sparql_11.ParseException; + +/** + * Interface that defines the WhereClause as per + * http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#rWhereClause + * + * @param <T> + * The Builder type that the clause is part of. + */ +public interface WhereClause<T extends AbstractQueryBuilder<T>> { + + /** + * Adds a triple as to the where clause. + * + * @param t + * The triple to add + * @return The Builder for chaining. + */ + public T addWhere(Triple t); + + /** + * Adds a triple as to the where clause. + * + * @param t + * The triple to add + * @return The Builder for chaining. + */ + public T addWhere(FrontsTriple t); + + /** + * Adds a triple to the where clause. + * + * See {@link AbstractQueryBuilder#makeNode} for conversion of the param values. + * + * @param s + * The subject. + * @param p + * The predicate. + * @param o + * The object. + * @return The Builder for chaining. + */ + public T addWhere(Object s, Object p, Object o); + + /** + * Adds an optional triple as to the where clause. + * + * @param t + * The triple to add + * @return The Builder for chaining. + */ + public T addOptional(Triple t); + + /** + * Adds an optional triple as to the where clause. + * + * @param t + * The triple to add + * @return The Builder for chaining. + */ + public T addOptional(FrontsTriple t); + + /** + * Adds an optional triple to the where clause. + * + * See {@link AbstractQueryBuilder#makeNode} for conversion of the param values. + * + * @param s + * The subject. + * @param p + * The predicate. + * @param o + * The object. + * @return The Builder for chaining. + */ + public T addOptional(Object s, Object p, Object o); + + /** + * Adds a filter to the where clause + * + * @param expression + * the expression to evaluate for the filter. + * @return @return The Builder for chaining. + * @throws ParseException + * If the expression can not be parsed. + */ + public T addFilter(String expression) throws ParseException; + + /** + * Add a sub query. + * + * @param subQuery + * The subquery as defined by a SelectBuilder. + * @return This builder for chaining. + */ + public T addSubQuery(SelectBuilder subQuery); + + /** + * Add a union. + * + * @param union + * The union as defined by a SelectBuilder. + * @return This builder for chaining. + */ + public T addUnion(SelectBuilder union); + + /** + * 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 T addGraph(Object graph, SelectBuilder subQuery); + + /** + * Get the Where handler for this clause. + * @return The WhereHandler used by this clause. + */ + public WhereHandler getWhereHandler(); + +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/package-info.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/package-info.java new file mode 100644 index 0000000..e98871a --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/clauses/package-info.java @@ -0,0 +1,7 @@ +/** + * Interfaces that describe various SPARQL clauses as per + * http://www.w3.org/TR/2013/REC-sparql11-query-20130321. + * + * These classes are used to compose consistent interfaces for specific builder implementations. + */ +package org.apache.jena.arq.querybuilder.clauses; \ No newline at end of file diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/ConstructHandler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/ConstructHandler.java new file mode 100644 index 0000000..55f1794 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/ConstructHandler.java @@ -0,0 +1,89 @@ +/* + * 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.handlers; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.jena.arq.querybuilder.rewriters.AbstractRewriter; + +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.sparql.core.BasicPattern; +import com.hp.hpl.jena.sparql.core.Var; +import com.hp.hpl.jena.sparql.syntax.Template; + +/** + * The handler for construct clauses. + * + */ +public class ConstructHandler implements Handler { + private final Query query; + private List<Triple> constructs; + + /** + * The constructor + * @param query The query that this handler will be modifying. + */ + public ConstructHandler(Query query) { + this.query = query; + constructs = new ArrayList<Triple>(); + if (query.getConstructTemplate() != null) { + for (Triple t : query.getConstructTemplate().getTriples()) { + constructs.add(t); + } + } + } + + /** + * Add a triple to the construct statement. + * @param t The triple to add. + */ + public void addConstruct(Triple t) { + constructs.add(t); + query.setConstructTemplate(new Template(BasicPattern.wrap(constructs))); + } + + /** + * Add all the construct handlers from the handler argument to this construct. + * @param handler The construct handler to copy from. + */ + public void addAll(ConstructHandler handler) { + constructs.addAll(handler.constructs); + query.setConstructTemplate(new Template(BasicPattern.wrap(constructs))); + } + + @Override + public void setVars(Map<Var, Node> values) { + if (values.isEmpty()) { + return; + } + AbstractRewriter<Node> rw = new AbstractRewriter<Node>(values) { + }; + query.setConstructTemplate(new Template(BasicPattern.wrap(rw + .rewrite(constructs)))); + } + + @Override + public void build() { + // there are no special operations for the build. + } + +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/DatasetHandler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/DatasetHandler.java new file mode 100644 index 0000000..e829e56 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/DatasetHandler.java @@ -0,0 +1,149 @@ +/* + * 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.handlers; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.sparql.core.Var; + +/** + * Handler for a dataset. + * + */ +public class DatasetHandler implements Handler { + + // the query to manage + private final Query query; + + /** + * Constructor. + * @param query The query the handler will manage. + */ + public DatasetHandler(Query query) { + this.query = query; + } + + /** + * Add all the dataset information from the handler argument. + * @param datasetHandler The handler to copy from. + */ + public void addAll(DatasetHandler datasetHandler) { + from(datasetHandler.query.getGraphURIs()); + fromNamed(datasetHandler.query.getNamedGraphURIs()); + } + + /** + * Add a graph name to the from named list. + * @param graphName The graph name to add. + */ + public void fromNamed(String graphName) { + query.addNamedGraphURI(graphName); + } + + /** + * Add the graph names to the from named list. + * + * The names are ordered in as defined in the collection. + * + * @param graphNames The from names to add. + */ + public void fromNamed(Collection<String> graphNames) { + for (String uri : graphNames) { + query.addNamedGraphURI(uri); + } + } + + /** + * Add the graph names to the from list. + * @param graphName the name to add. + */ + public void from(String graphName) { + query.addGraphURI(graphName); + } + + /** + * Add the graph names to the named list. + * + * The names are ordered in as defined in the collection. + * + * @param graphNames The names to add. + */ + public void from(Collection<String> graphNames) { + for (String uri : graphNames) { + query.addGraphURI(uri); + } + } + + /** + * Set the variables for field names that contain lists of strings. + * + * Strings that start with "?" are assumed to be variable names and will be replaced + * with matching node.toString() values. + * + * @param values The values to set. + * @param fieldName The field name in Query that contain a list of strings. + */ + private void setVars(Map<Var, Node> values, String fieldName) { + if (values.isEmpty()) { + return; + } + try { + Field f = Query.class.getDeclaredField(fieldName); + f.setAccessible(true); + @SuppressWarnings("unchecked") + List<String> orig = (List<String>) f.get(query); + List<String> lst = null; + if (orig != null) { + lst = new ArrayList<String>(); + for (String s : orig) { + Node n = null; + if (s.startsWith("?")) { + Var v = Var.alloc(s.substring(1)); + n = values.get(v); + } + lst.add(n == null ? s : n.toString()); + } + f.set(query, lst); + } + } catch (NoSuchFieldException e) { + throw new IllegalStateException(e.getMessage(), e); + } catch (SecurityException e) { + throw new IllegalStateException(e.getMessage(), e); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e.getMessage(), e); + } + } + + @Override + public void setVars(Map<Var, Node> values) { + setVars(values, "namedGraphURIs"); + setVars(values, "graphURIs"); + } + + @Override + public void build() { + // nothing special to do + } + +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/Handler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/Handler.java new file mode 100644 index 0000000..a6bf8d5 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/Handler.java @@ -0,0 +1,42 @@ +/* + * 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.handlers; + +import java.util.Map; + +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.sparql.core.Var; + +/** + * The base interface for handlers. + * + */ +public interface Handler { + /** + * Set the values for variables managed by the handler implementation. + * This method is called by the builder to set values handled by this Handler implementation. + * @param values The map of variable to node value. + */ + public void setVars(Map<Var, Node> values); + + /** + * Called by the build process for this handler to perform any adjustments to the query before + * the build completes. The adjustments are made after setVars() has been called. + */ + public void build(); +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/PrologHandler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/PrologHandler.java new file mode 100644 index 0000000..a821e4d --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/PrologHandler.java @@ -0,0 +1,126 @@ +/* + * 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.handlers; + +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.apache.jena.riot.system.IRIResolver; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.shared.PrefixMapping; +import com.hp.hpl.jena.sparql.core.Var; + +/** + * The proglog handler + * + */ +public class PrologHandler implements Handler { + + // the query to modify. + private final Query query; + + /** + * Constructor. + * @param query The query to handle. + */ + public PrologHandler(Query query) { + this.query = query; + } + + /** + * get the canonical prefix name. + * + * Removes ':' from the end of the name if present. + * + * @param x The prefix name + * @return The prefix name with the trialing ':' removed. + */ + private String canonicalPfx(String x) { + if (x.endsWith(":")) + return x.substring(0, x.length() - 1); + return x; + } + + /** + * Set the base for the query. This is the IRI against which relative names will be resolved. + * @param resolver The IRIResolver to set the base from. + */ + public void setBase(IRIResolver resolver) { + query.setBaseURI(resolver); + + } + + /** + * Set the base for the query. This is the IRI against which relative names will be resolved. + * @param base The string to set the base from. + */ + public void setBase(String base) { + query.setBaseURI(base); + } + + /** + * Add a prefix to the prefix mapping. + * @param pfx The prefix to add. + * @param uri The uri to resolve the prefix to. + */ + public void addPrefix(String pfx, String uri) { + query.setPrefix(canonicalPfx(pfx), uri); + } + + /** + * Add the map of prefixes to the query prefixes. + * @param prefixes The map of prefixs to URIs. + */ + public void addPrefixes(Map<String, String> prefixes) { + for (Map.Entry<String, String> e : prefixes.entrySet()) { + addPrefix(e.getKey(), e.getValue()); + } + } + + /** + * Add prefixes from a prefix mapping. + * @param prefixes THe prefix mapping to add from. + */ + public void addPrefixes(PrefixMapping prefixes) { + query.getPrefixMapping().setNsPrefixes(prefixes); + } + + /** + * Add the settings from the prolog handler argument. + * @param pfxHandler The PrologHandler to read from + */ + public void addAll(PrologHandler pfxHandler) { + String val = StringUtils.defaultIfEmpty(pfxHandler.query.getBaseURI(), + query.getBaseURI()); + if (val != null) { + setBase(val); + } + addPrefixes(pfxHandler.query.getPrefixMapping()); + } + + @Override + public void setVars(Map<Var, Node> values) { + // nothing to do + } + + @Override + public void build() { + // no special operation to perform + } +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/SelectHandler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/SelectHandler.java new file mode 100644 index 0000000..70e94a7 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/SelectHandler.java @@ -0,0 +1,133 @@ +/* + * 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.handlers; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; + +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.sparql.core.Var; +import com.hp.hpl.jena.sparql.core.VarExprList; + +/** + * A Select clause handler. + * + */ +public class SelectHandler implements Handler { + + // the query to handle + private final Query query; + + /** + * Constructor. + * @param query The query to manage. + */ + public SelectHandler(Query query) { + this.query = query; + setDistinct(query.isDistinct()); + setReduced(query.isReduced()); + } + + /** + * Set the distinct flag. + * Set or unset the distinct flag. + * Will set the reduced flag if it was previously set. + * @param state the state to set the distinct flag to. + */ + public void setDistinct(boolean state) { + query.setDistinct(state); + if (state) { + query.setReduced(false); + } + } + + /** + * Set the reduced flag. + * Set or unset the reduced flag. + * Will set the reduced flag if it was previously set. + * @param state the state to set the reduced flag to. + */ + public void setReduced(boolean state) { + query.setReduced(state); + if (state) { + query.setDistinct(false); + } + } + + /** + * Add a variable to the select. + * If the variable is the variables are set to star. + * @param var The variable to add. + */ + public void addVar(Var var) { + if (var == null) { + query.setQueryResultStar(true); + } else { + query.setQueryResultStar(false); + query.addResultVar(var); + } + } + + /** + * Get the list of variables from the query. + * @return The list of variables in the query. + */ + public List<Var> getVars() { + return query.getProjectVars(); + } + + /** + * Add all the variables from the select handler variable. + * @param selectHandler The select handler to copy the variables from. + */ + public void addAll(SelectHandler selectHandler) { + + setReduced(selectHandler.query.isReduced()); + setDistinct(selectHandler.query.isDistinct()); + query.setQueryResultStar(selectHandler.query.isQueryResultStar()); + + try { + Field f = Query.class.getDeclaredField("projectVars"); + f.setAccessible(true); + VarExprList projectVars = (VarExprList) f.get(selectHandler.query); + f.set(query, new VarExprList(projectVars)); + } catch (NoSuchFieldException e) { + throw new IllegalStateException(e); + } catch (SecurityException e) { + throw new IllegalStateException(e); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } + } + + @Override + public void setVars(Map<Var, Node> values) { + // nothing to do + } + + @Override + public void build() { + if (query.getProject().getVars().isEmpty()) { + query.setQueryResultStar(true); + } + // handle the SELECT * case + query.getProjectVars(); + } +} diff --git a/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/SolutionModifierHandler.java b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/SolutionModifierHandler.java new file mode 100644 index 0000000..50838f5 --- /dev/null +++ b/jena-extras/jena-querybuilder/src/main/java/org/apache/jena/arq/querybuilder/handlers/SolutionModifierHandler.java @@ -0,0 +1,269 @@ +/* + * 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.handlers; + +import java.io.ByteArrayInputStream; +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; + +import org.apache.jena.arq.querybuilder.rewriters.ExprRewriter; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.SortCondition; +import com.hp.hpl.jena.sparql.core.Var; +import com.hp.hpl.jena.sparql.core.VarExprList; +import com.hp.hpl.jena.sparql.expr.Expr; +import com.hp.hpl.jena.sparql.expr.ExprList; +import com.hp.hpl.jena.sparql.expr.ExprVar; +import com.hp.hpl.jena.sparql.lang.sparql_11.ParseException; +import com.hp.hpl.jena.sparql.lang.sparql_11.SPARQLParser11; + +/** + * The Solution Modifier handerl. + * + */ +public class SolutionModifierHandler implements Handler { + /** + * The order for the ORDER BY modifiers. + */ + public e
<TRUNCATED>
