/*
* (c) Copyright 2011 Epimorphics Ltd.
* All rights reserved.
* [See end of file]
*/
package opexec;
import java.io.StringReader ;
import org.openjena.atlas.lib.StrUtils ;
import org.openjena.atlas.logging.Log ;
import com.hp.hpl.jena.query.ARQ ;
import com.hp.hpl.jena.query.Query ;
import com.hp.hpl.jena.query.QueryExecution ;
import com.hp.hpl.jena.query.QueryExecutionFactory ;
import com.hp.hpl.jena.query.QueryFactory ;
import com.hp.hpl.jena.query.ResultSetFormatter ;
import com.hp.hpl.jena.rdf.model.Model ;
import com.hp.hpl.jena.rdf.model.ModelFactory ;
import com.hp.hpl.jena.sparql.algebra.op.OpBGP ;
import com.hp.hpl.jena.sparql.algebra.op.OpFilter ;
import com.hp.hpl.jena.sparql.core.BasicPattern ;
import com.hp.hpl.jena.sparql.engine.ExecutionContext ;
import com.hp.hpl.jena.sparql.engine.QueryIterator ;
import com.hp.hpl.jena.sparql.engine.main.OpExecutor ;
import com.hp.hpl.jena.sparql.engine.main.OpExecutorFactory ;
import com.hp.hpl.jena.sparql.engine.main.QC ;
import com.hp.hpl.jena.sparql.engine.main.StageBuilder ;
/** Example skeleton for a query engine.
* To just extend ARQ by custom basic graph pattern matching (a very common case)
* see the arq.examples.bgpmatching package */
public class OpExecutorExample //extends QueryEngineMain
{
// UNFINISHED
// Check where OpExecutorFactory.create happens.
/* To install a custom OpExecutor, the application needs
*
*
* The example MyQueryEngine shows how to take over the
* execution of a SPARQL algebra expression. This allows
* customization of optimizations running before query execution
* starts.
*
* An OpExecutor controls the running of an algebra expression.
* An executor needs to cope with the fact a dataset might be composed
* of a mixture of graphs, and that it might be be being called for any
* kind of storage unit, not just one it is designed for.
*
* Thsi is done by having a chain (via subclassing) of OpExecutors,
* with the base class being hthe general purpose one for ARQ that can
* operate on any data storage layer.
*
*/
static void init()
{
// Wire the new factory into the system.
ARQ.init() ;
// *** Where is the factory choosen?
OpExecutorFactory current = QC.getFactory(ARQ.getContext()) ;
// maybe null
QC.setFactory(ARQ.getContext(), new MyOpExecutorFactory(current)) ;
}
public static void main(String ...argv)
{
Log.setLog4j() ;
init() ;
Model m = data() ;
String s = "SELECT DISTINCT ?s { ?s ?p ?o FILTER (?o=12) } " ;
Query query = QueryFactory.create(s) ;
QueryExecution qExec = QueryExecutionFactory.create(query, m) ;
ResultSetFormatter.out(qExec.execSelect()) ;
qExec.close() ;
}
private static Model data()
{
String s = StrUtils.strjoinNL("
12 .",
"
15 .") ; Model m = ModelFactory.createDefaultModel() ; m.read(new StringReader(s), null , "TTL") ; return m ; } // This is a simple example. // For execution logging, see: // http://openjena.org/wiki/ARQ/Explain // which printout more information. static class MyOpExecutor extends OpExecutor { protected MyOpExecutor(ExecutionContext execCxt) { super(execCxt) ; } @Override protected QueryIterator execute(OpBGP opBGP, QueryIterator input) { System.out.print("Execute: "+opBGP) ; // This is an illustration - it's a copy of the default implementation BasicPattern pattern = opBGP.getPattern() ; return StageBuilder.execute(pattern, input, execCxt) ; } @Override protected QueryIterator execute(OpFilter opFilter, QueryIterator input) { System.out.print("Execute: "+opFilter) ; return super.execute(opFilter, input) ; } } /** A factory to make OpExecutors */ static class MyOpExecutorFactory implements OpExecutorFactory { private final OpExecutorFactory other ; public MyOpExecutorFactory(OpExecutorFactory other) { this.other = other ; } public OpExecutor create(ExecutionContext execCxt) { return new MyOpExecutor(execCxt) ; } } } /* * (c) Copyright 2011 Epimorphics Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */