/* * $Id$ * * This file is part of the OpenLink Software Virtuoso Open-Source (VOS) * project. * * Copyright (C) 1998-2012 OpenLink Software * * This project is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; only version 2 of the License, dated June 1991. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ package virtuoso.jena.driver; import java.sql.ResultSetMetaData; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; import java.util.concurrent.TimeUnit; import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.graph.Triple; import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.shared.JenaException; import com.hp.hpl.jena.sparql.core.ResultBinding; import com.hp.hpl.jena.sparql.core.Var; import com.hp.hpl.jena.sparql.engine.binding.Binding; import com.hp.hpl.jena.sparql.engine.binding.BindingHashMap; import com.hp.hpl.jena.sparql.engine.binding.BindingMap; import com.hp.hpl.jena.sparql.engine.iterator.QueryIterConcat; import com.hp.hpl.jena.sparql.util.Context; import com.hp.hpl.jena.sparql.util.ModelUtils; import com.hp.hpl.jena.util.FileManager; public class VirtuosoQueryExecution implements QueryExecution { private QueryIterConcat output = null; private String virt_graph = null; private VirtGraph graph; private String virt_query; private QuerySolution m_arg = null; private java.sql.Statement stmt = null; public VirtuosoQueryExecution(String query, VirtGraph _graph) { graph = _graph; virt_graph = graph.getGraphName(); virt_query = query; } public ResultSet execSelect() { ResultSet ret = null; try { stmt = graph.createStatement(); java.sql.ResultSet rs = stmt.executeQuery(getQueryString()); return new VResultSet(graph, rs); } catch (Exception e) { throw new JenaException("Can not create ResultSet.:" + e); } } public void setFileManager(FileManager arg) { throw new JenaException("UnsupportedMethodException"); } public void setInitialBinding(QuerySolution arg) { m_arg = arg; } public Dataset getDataset() { return new VirtDataSource(graph); } public Context getContext() { return null; } public Model execConstruct() { return execConstruct(ModelFactory.createDefaultModel()); } public Model execConstruct(Model model) { try { stmt = graph.createStatement(); java.sql.ResultSet rs = stmt.executeQuery(getQueryString()); ResultSetMetaData rsmd = rs.getMetaData(); while (rs.next()) { Node s = VirtGraph.Object2Node(rs.getObject(1)); Node p = VirtGraph.Object2Node(rs.getObject(2)); Node o = VirtGraph.Object2Node(rs.getObject(3)); com.hp.hpl.jena.rdf.model.Statement st = ModelUtils .tripleToStatement(model, new Triple(s, p, o)); if (st != null) model.add(st); } rs.close(); stmt.close(); stmt = null; } catch (Exception e) { throw new JenaException("Convert results are FAILED.:" + e); } return model; } public Model execDescribe() { return execDescribe(ModelFactory.createDefaultModel()); } public Model execDescribe(Model model) { try { stmt = graph.createStatement(); java.sql.ResultSet rs = stmt.executeQuery(getQueryString()); ResultSetMetaData rsmd = rs.getMetaData(); while (rs.next()) { Node s = VirtGraph.Object2Node(rs.getObject(1)); Node p = VirtGraph.Object2Node(rs.getObject(2)); Node o = VirtGraph.Object2Node(rs.getObject(3)); com.hp.hpl.jena.rdf.model.Statement st = ModelUtils .tripleToStatement(model, new Triple(s, p, o)); if (st != null) model.add(st); } rs.close(); stmt.close(); stmt = null; } catch (Exception e) { throw new JenaException("Convert results are FAILED.:" + e); } return model; } public boolean execAsk() { boolean ret = false; try { stmt = graph.createStatement(); java.sql.ResultSet rs = stmt.executeQuery(getQueryString()); ResultSetMetaData rsmd = rs.getMetaData(); while (rs.next()) { if (rs.getInt(1) == 1) ret = true; } rs.close(); stmt.close(); stmt = null; } catch (Exception e) { throw new JenaException("Convert results are FAILED.:" + e); } return ret; } public void abort() { if (stmt != null) try { stmt.cancel(); } catch (Exception e) { } } public void close() { if (stmt != null) try { stmt.cancel(); stmt.close(); } catch (Exception e) { } } private String substBindings(String query) { if (m_arg == null) return query; StringBuffer buf = new StringBuffer(); String delim = " ,)(;."; int i = 0; char ch; int qlen = query.length(); while (i < qlen) { ch = query.charAt(i++); if (ch == '\\') { buf.append(ch); if (i < qlen) buf.append(query.charAt(i++)); } else if (ch == '"' || ch == '\'') { char end = ch; buf.append(ch); while (i < qlen) { ch = query.charAt(i++); buf.append(ch); if (ch == end) break; } } else if (ch == '?') { // Parameter String varData = null; int j = i; while (j < qlen && delim.indexOf(query.charAt(j)) < 0) j++; if (j != i) { String varName = query.substring(i, j); RDFNode val = m_arg.get(varName); if (val != null) { varData = VirtGraph.Node2Str(val.asNode()); i = j; } } if (varData != null) buf.append(varData); else buf.append(ch); } else { buf.append(ch); } } return buf.toString(); } private String getQueryString() { StringBuffer sb = new StringBuffer("sparql\n "); if (graph.getRuleSet() != null) sb.append(" define input:inference '" + graph.getRuleSet() + "'\n"); if (graph.getSameAs()) sb.append(" define input:same-as \"yes\"\n"); if (!graph.getReadFromAllGraphs()) sb.append(" define input:default-graph-uri <" + graph.getGraphName() + "> \n"); sb.append(substBindings(virt_query)); return sb.toString(); } // /=== Inner class =========================================== public class VResultSet implements com.hp.hpl.jena.query.ResultSet { ResultSetMetaData rsmd; java.sql.ResultSet rs; boolean v_finished = false; boolean v_prefetched = false; VirtModel m; BindingMap v_row; List<String> resVars = new LinkedList(); int row_id = 0; protected VResultSet(VirtGraph _g, java.sql.ResultSet _rs) { rs = _rs; m = new VirtModel(_g); try { rsmd = rs.getMetaData(); for (int i = 1; i <= rsmd.getColumnCount(); i++) resVars.add(rsmd.getColumnLabel(i)); if (virt_graph != null && !virt_graph.equals("virt:DEFAULT")) resVars.add("graph"); } catch (Exception e) { throw new JenaException( "ViruosoResultBindingsToJenaResults is FAILED.:" + e); } } public boolean hasNext() { if (!v_finished && !v_prefetched) moveForward(); return !v_finished; } public QuerySolution next() { Binding binding = nextBinding(); if (v_finished) throw new NoSuchElementException(); return new ResultBinding(m, binding); } public QuerySolution nextSolution() { return next(); } public Binding nextBinding() { if (!v_finished && !v_prefetched) moveForward(); v_prefetched = false; if (v_finished) throw new NoSuchElementException(); return v_row; } public int getRowNumber() { return row_id; } public List<String> getResultVars() { return resVars; } public Model getResourceModel() { return m; } protected void finalize() throws Throwable { if (!v_finished) try { close(); } catch (Exception e) { } } protected void moveForward() throws JenaException { try { if (!v_finished && rs.next()) { extractRow(); v_prefetched = true; } else close(); } catch (Exception e) { throw new JenaException("Convert results are FAILED.:" + e); } } protected void extractRow() throws Exception { v_row = new BindingHashMap(); row_id++; try { for (int i = 1; i <= rsmd.getColumnCount(); i++) { Node n = VirtGraph.Object2Node(rs.getObject(i)); if (n != null) v_row.add(Var.alloc(rsmd.getColumnLabel(i)), n); } if (virt_graph != null && !virt_graph.equals("virt:DEFAULT")) v_row.add(Var.alloc("graph"), Node.createURI(virt_graph)); } catch (Exception e) { throw new JenaException( "ViruosoResultBindingsToJenaResults is FAILED.:" + e); } } public void remove() throws java.lang.UnsupportedOperationException { throw new UnsupportedOperationException(this.getClass().getName() + ".remove"); } private void close() { if (!v_finished) { if (rs != null) { try { rs.close(); rs = null; } catch (Exception e) { } } } v_finished = true; } } public Iterator<Triple> execConstructTriples() { // TODO Auto-generated method stub return null; } public Iterator<Triple> execDescribeTriples() { // TODO Auto-generated method stub return null; } public Query getQuery() { // TODO Auto-generated method stub return null; } public void setTimeout(long arg0) { // TODO Auto-generated method stub } public void setTimeout(long arg0, TimeUnit arg1) { // TODO Auto-generated method stub } public void setTimeout(long arg0, long arg1) { // TODO Auto-generated method stub } public void setTimeout(long arg0, TimeUnit arg1, long arg2, TimeUnit arg3) { // TODO Auto-generated method stub } public long getTimeout1() { // TODO Auto-generated method stub return 0; } public long getTimeout2() { // TODO Auto-generated method stub return 0; } }