/* * 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.sparql.util ; import java.util.List ; import org.apache.jena.query.* ; import org.apache.jena.rdf.model.Model ; import org.apache.jena.rdf.model.RDFNode ; import org.apache.jena.riot.Lang ; import org.apache.jena.riot.RDFDataMgr ; import org.apache.jena.riot.ResultSetMgr ; import org.apache.jena.shared.PrefixMapping ; import org.apache.jena.shared.impl.PrefixMappingImpl ; import org.apache.jena.sparql.ARQConstants ; import org.apache.jena.sparql.ARQException ; import org.apache.jena.sparql.algebra.Algebra ; import org.apache.jena.sparql.algebra.Op ; import org.apache.jena.sparql.algebra.OpVars ; import org.apache.jena.sparql.algebra.op.OpProject ; import org.apache.jena.sparql.core.DatasetGraph ; import org.apache.jena.sparql.core.Prologue ; import org.apache.jena.sparql.core.Var ; import org.apache.jena.sparql.engine.QueryIterator ; import org.apache.jena.sparql.resultset.PlainFormat ; import org.apache.jena.sparql.resultset.RDFOutput ; import org.apache.jena.sparql.resultset.ResultSetApply ; import org.apache.jena.sparql.resultset.ResultsFormat ; import org.apache.jena.sparql.vocabulary.ResultSetGraphVocab ; /** Some utilities for query processing. */ public class QueryExecUtils { protected static PrefixMapping globalPrefixMap = new PrefixMappingImpl() ; static { globalPrefixMap.setNsPrefix("rdf", ARQConstants.rdfPrefix) ; globalPrefixMap.setNsPrefix("rdfs", ARQConstants.rdfsPrefix) ; globalPrefixMap.setNsPrefix("xsd", ARQConstants.xsdPrefix) ; globalPrefixMap.setNsPrefix("owl" , ARQConstants.owlPrefix) ; globalPrefixMap.setNsPrefix("ex" , "http://example.org/") ; globalPrefixMap.setNsPrefix("ns" , "http://example.org/ns#") ; globalPrefixMap.setNsPrefix("" , "http://example/") ; } protected static Prologue dftPrologue = new Prologue(globalPrefixMap) ; public static void executeQuery(QueryExecution queryExecution) { executeQuery(null, queryExecution) ; } public static void executeQuery(Prologue prologue, QueryExecution queryExecution) { executeQuery(prologue, queryExecution, ResultsFormat.FMT_TEXT) ; } public static void executeQuery(Prologue prologue, QueryExecution queryExecution, ResultsFormat outputFormat) { Query query = queryExecution.getQuery() ; if ( prologue == null ) prologue = query.getPrologue() ; if ( prologue == null ) prologue = dftPrologue ; if ( query.isSelectType() ) doSelectQuery(prologue, queryExecution, outputFormat) ; if ( query.isDescribeType() ) doDescribeQuery(prologue, queryExecution, outputFormat) ; if ( query.isConstructType() ) doConstructQuery(prologue, queryExecution, outputFormat) ; if ( query.isAskType() ) doAskQuery(prologue, queryExecution, outputFormat) ; queryExecution.close() ; } public static void execute(Op op, DatasetGraph dsg) { execute(op, dsg, ResultsFormat.FMT_TEXT) ; } public static void execute(Op op, DatasetGraph dsg, ResultsFormat outputFormat) { QueryIterator qIter = Algebra.exec(op, dsg) ; List<String> vars = null ; if ( op instanceof OpProject ) vars = Var.varNames(((OpProject)op).getVars()) ; else // The variables defined in patterns (not Filters, nor NOT EXISTS, // nor ORDER BY) vars = Var.varNames(OpVars.visibleVars(op)) ; ResultSet results = ResultSetFactory.create(qIter, vars) ; outputResultSet(results, null, outputFormat) ; } @SuppressWarnings("deprecation") public static void outputResultSet(ResultSet results, Prologue prologue, ResultsFormat outputFormat) { // Proper ResultSet formats. Lang lang = ResultsFormat.convert(outputFormat) ; if ( lang != null ) { ResultSetMgr.write(System.out, results, lang) ; System.out.flush() ; return ; } // Old way. boolean done = false ; if ( prologue == null ) prologue = new Prologue(globalPrefixMap) ; if ( outputFormat.equals(ResultsFormat.FMT_UNKNOWN) ) outputFormat = ResultsFormat.FMT_TEXT ; if ( outputFormat.equals(ResultsFormat.FMT_NONE) || outputFormat.equals(ResultsFormat.FMT_COUNT) ) { int count = ResultSetFormatter.consume(results) ; if ( outputFormat.equals(ResultsFormat.FMT_COUNT) ) { System.out.println("Count = " + count) ; } done = true ; } if ( outputFormat.equals(ResultsFormat.FMT_RDF_XML) || outputFormat.equals(ResultsFormat.FMT_RDF_N3) || outputFormat.equals(ResultsFormat.FMT_RDF_TTL) ) { Model m = RDFOutput.encodeAsModel(results) ; m.setNsPrefixes(prologue.getPrefixMapping()) ; m.setNsPrefix("rs", ResultSetGraphVocab.getURI()) ; RDFDataMgr.write(System.out, m, Lang.TURTLE) ; done = true ; } if ( outputFormat.equals(ResultsFormat.FMT_RS_XML) ) { ResultSetFormatter.outputAsXML(System.out, results) ; done = true ; } if ( outputFormat.equals(ResultsFormat.FMT_RS_JSON) ) { ResultSetFormatter.outputAsJSON(System.out, results) ; done = true ; } if ( outputFormat.equals(ResultsFormat.FMT_RS_SSE) ) { ResultSetFormatter.outputAsSSE(System.out, results, prologue) ; done = true ; } if ( outputFormat.equals(ResultsFormat.FMT_TEXT) ) { ResultSetFormatter.out(System.out, results, prologue) ; done = true ; } if ( outputFormat.equals(ResultsFormat.FMT_TUPLES) ) { PlainFormat pFmt = new PlainFormat(System.out, prologue) ; ResultSetApply a = new ResultSetApply(results, pFmt) ; a.apply() ; done = true ; } if ( outputFormat.equals(ResultsFormat.FMT_RS_CSV) ) { ResultSetFormatter.outputAsCSV(System.out, results) ; done = true ; } if ( outputFormat.equals(ResultsFormat.FMT_RS_TSV) ) { ResultSetFormatter.outputAsTSV(System.out, results) ; done = true ; } if ( outputFormat.equals(ResultsFormat.FMT_RS_BIO) ) { ResultSetFormatter.outputAsBIO(System.out, results) ; done = true ; } if ( !done ) System.err.println("Unknown format request: " + outputFormat) ; results = null ; System.out.flush() ; } private static void doSelectQuery(Prologue prologue, QueryExecution qe, ResultsFormat outputFormat) { if ( prologue == null ) prologue = qe.getQuery().getPrologue() ; if ( outputFormat == null || outputFormat == ResultsFormat.FMT_UNKNOWN ) outputFormat = ResultsFormat.FMT_TEXT ; ResultSet results = qe.execSelect() ; outputResultSet(results, prologue, outputFormat) ; } private static void doDescribeQuery(Prologue prologue, QueryExecution qe, ResultsFormat outputFormat) { if ( outputFormat == null || outputFormat == ResultsFormat.FMT_UNKNOWN ) outputFormat = ResultsFormat.FMT_RDF_TTL ; Model r = qe.execDescribe() ; writeModel(prologue, r, outputFormat) ; } private static void doConstructQuery(Prologue prologue, QueryExecution qe, ResultsFormat outputFormat) { if ( outputFormat == null || outputFormat == ResultsFormat.FMT_UNKNOWN ) outputFormat = ResultsFormat.FMT_RDF_TTL ; Model r = qe.execConstruct() ; writeModel(prologue, r, outputFormat) ; } private static void writeModel(Prologue prologue, Model model, ResultsFormat outputFormat) { if ( outputFormat == null || outputFormat == ResultsFormat.FMT_UNKNOWN ) outputFormat = ResultsFormat.FMT_TEXT ; if ( outputFormat.equals(ResultsFormat.FMT_NONE) ) return ; if ( outputFormat.equals(ResultsFormat.FMT_TEXT) ) { System.out.println("# ======== ") ; RDFDataMgr.write(System.out, model, Lang.TURTLE) ; System.out.println("# ======== ") ; return ; } if ( outputFormat.equals(ResultsFormat.FMT_RDF_XML) ) { model.write(System.out, "RDF/XML-ABBREV", null) ; return ; } if ( outputFormat.equals(ResultsFormat.FMT_RDF_TTL) ) { model.write(System.out, "N3", null) ; return ; } if ( outputFormat.equals(ResultsFormat.FMT_RDF_N3) ) { model.write(System.out, "N3", null) ; return ; } if ( outputFormat.equals(ResultsFormat.FMT_RDF_NT) ) { model.write(System.out, "N-TRIPLES", null) ; return ; } System.err.println("Unknown format: " + outputFormat) ; } private static void doAskQuery(Prologue prologue, QueryExecution qe, ResultsFormat outputFormat) { boolean b = qe.execAsk() ; if ( outputFormat == null || outputFormat == ResultsFormat.FMT_UNKNOWN ) outputFormat = ResultsFormat.FMT_TEXT ; if ( outputFormat.equals(ResultsFormat.FMT_NONE) ) return ; if ( outputFormat.equals(ResultsFormat.FMT_RS_XML) ) { ResultSetFormatter.outputAsXML(System.out, b) ; return ; } if ( outputFormat.equals(ResultsFormat.FMT_RDF_N3) || outputFormat.equals(ResultsFormat.FMT_RDF_TTL) ) { RDFOutput.outputAsRDF(System.out, "TURTLE", b) ; System.out.flush() ; return ; } if ( outputFormat.equals(ResultsFormat.FMT_RS_JSON) ) { ResultSetFormatter.outputAsJSON(System.out, b) ; return ; } if ( outputFormat.equals(ResultsFormat.FMT_TEXT) ) { // ResultSetFormatter.out(System.out, b) ; System.out.println("Ask => " + (b ? "Yes" : "No")) ; return ; } if ( outputFormat.equals(ResultsFormat.FMT_RS_CSV) ) { ResultSetFormatter.outputAsCSV(System.out, b) ; return ; } if ( outputFormat.equals(ResultsFormat.FMT_RS_TSV) ) { ResultSetFormatter.outputAsTSV(System.out, b) ; return ; } System.err.println("Unknown format: " + outputFormat) ; } /** * Execute a query, expecting the result to be one row, one column. Return * that one RDFNode */ public static RDFNode getExactlyOne(String qs, Model model) { return getExactlyOne(qs, DatasetFactory.create(model)) ; } /** * Execute a query, expecting the result to be one row, one column. Return * that one RDFNode */ public static RDFNode getExactlyOne(String qs, Dataset ds) { Query q = QueryFactory.create(qs) ; if ( q.getResultVars().size() != 1 ) throw new ARQException("getExactlyOne: Must have exactly one result columns") ; String varname = q.getResultVars().get(0) ; QueryExecution qExec = QueryExecutionFactory.create(q, ds) ; return getExactlyOne(qExec, varname) ; } /** * Execute, expecting the result to be one row, one column. Return that one * RDFNode or throw an exception */ public static RDFNode getExactlyOne(QueryExecution qExec, String varname) { try { ResultSet rs = qExec.execSelect() ; if ( !rs.hasNext() ) throw new ARQException("Not found: var ?" + varname) ; QuerySolution qs = rs.nextSolution() ; RDFNode r = qs.get(varname) ; if ( rs.hasNext() ) throw new ARQException("More than one: var ?" + varname) ; return r ; } finally { qExec.close() ; } } /** * Execute, expecting the result to be one row, one column. Return that one * RDFNode or null Throw excpetion if more than one. */ public static RDFNode getOne(QueryExecution qExec, String varname) { try { ResultSet rs = qExec.execSelect() ; if ( !rs.hasNext() ) return null ; QuerySolution qs = rs.nextSolution() ; RDFNode r = qs.get(varname) ; if ( rs.hasNext() ) { QuerySolution qs2 = rs.next() ; RDFNode r2 = qs2.get(varname) ; if ( rs.hasNext() ) throw new ARQException("More than one: var ?" + varname + " -> " + r + ", " + r2 + ", ...") ; else throw new ARQException("Found two matches: var ?" + varname + " -> " + r + ", " + r2) ; } return r ; } finally { qExec.close() ; } } }