Permalink
Browse files

implemented an RDFGraphSparqlEngine for Plantain, based on Sesame's a…

…lgebra.evaluation -- does *not* require a Repository
  • Loading branch information...
1 parent 32e4088 commit 077854b7bc51246484743743875a162deacacca3 @betehess betehess committed Nov 18, 2012
@@ -0,0 +1,26 @@
+package org.w3.banana.plantain
+
+import org.openrdf.query.{ BindingSet, TupleQueryResult }
+import org.openrdf.query.impl.MapBindingSet
+import info.aduna.iteration.CloseableIteration
+
+object PlantainUtil {
+
+ private class CloseableIterationAsIterator(iteration: CloseableIteration[_ <: BindingSet, _]) extends Iterator[BindingSet] {
+ def hasNext: Boolean = iteration.hasNext
+ def next(): BindingSet = iteration.next()
+ }
+
+ implicit class CloseableIterationW(val iteration: CloseableIteration[_ <: BindingSet, _]) extends AnyVal {
+ def toIterator: Iterator[BindingSet] = new CloseableIterationAsIterator(iteration)
+ }
+
+ implicit class Bindings(val bindings: Map[String, Plantain#Node]) extends AnyVal {
+ def asSesame: BindingSet = {
+ val bindingSet = new MapBindingSet(bindings.size)
+ bindings foreach { case (name, value) => bindingSet.addBinding(name, value.asSesame) }
+ bindingSet
+ }
+ }
+
+}
@@ -29,7 +29,7 @@ trait Plantain extends RDF {
type AskQuery = ParsedBooleanQuery
type Solution = BindingSet
// instead of TupleQueryResult so that it's eager instead of lazy
- type Solutions = Iterable[BindingSet]
+ type Solutions = Iterator[BindingSet]
}
@@ -41,7 +41,7 @@ object Plantain {
implicit val sparqlOps: SparqlOps[Plantain] = PlantainSparqlOps
-// implicit val graphQuery: RDFGraphQuery[Plantain] = PlantainGraphSparqlEngine
+ implicit val graphQuery: RDFGraphQuery[Plantain] = PlantainGraphSparqlEngine
implicit val rdfxmlReader: RDFReader[Plantain, RDFXML] = PlantainRDFXMLReader
@@ -55,20 +55,18 @@ object Plantain {
implicit val rdfWriterSelector: RDFWriterSelector[Plantain] = PlantainRDFWriter.selector //
-// implicit val solutionsWriterJson: SparqlSolutionsWriter[Plantain, SparqlAnswerJson] =
-// PlantainSolutionsWriter.solutionsWriterJson
-//
-// implicit val solutionsWriterXml: SparqlSolutionsWriter[Plantain, SparqlAnswerXml] =
-// PlantainSolutionsWriter.solutionsWriterXml
-//
-// implicit val solutionsWriterSelector: SparqlSolutionsWriterSelector[Plantain] = PlantainSolutionsWriter.solutionsWriterSelector
-//
-// implicit val queryResultsReaderJson: SparqlQueryResultsReader[Plantain, SparqlAnswerJson] =
-// PlantainQueryResultsReader.queryResultsReaderJson
-//
-// implicit val queryResultsReaderXml: SparqlQueryResultsReader[Plantain, SparqlAnswerXml] =
-// PlantainQueryResultsReader.queryResultsReaderXml
+ implicit val solutionsWriterJson: SparqlSolutionsWriter[Plantain, SparqlAnswerJson] =
+ PlantainSolutionsWriter.solutionsWriterJson
+ implicit val solutionsWriterXml: SparqlSolutionsWriter[Plantain, SparqlAnswerXml] =
+ PlantainSolutionsWriter.solutionsWriterXml
+ implicit val solutionsWriterSelector: SparqlSolutionsWriterSelector[Plantain] = PlantainSolutionsWriter.writerSelector
+
+ implicit val queryResultsReaderJson: SparqlQueryResultsReader[Plantain, SparqlAnswerJson] =
+ PlantainQueryResultsReader.queryResultsReaderJson
+
+ implicit val queryResultsReaderXml: SparqlQueryResultsReader[Plantain, SparqlAnswerXml] =
+ PlantainQueryResultsReader.queryResultsReaderXml
}
@@ -0,0 +1,57 @@
+package org.w3.banana.plantain
+
+import org.w3.banana._
+import org.openrdf.model.{ URI => SesameURI, _ }
+import org.openrdf.model.impl._
+import scala.collection.JavaConversions._
+import info.aduna.iteration.CloseableIteration
+import org.openrdf.query._
+import org.openrdf.query.impl._
+import scalaz.Id._
+import org.openrdf.query.algebra.evaluation.impl.EvaluationStrategyImpl
+import PlantainUtil._
+
+object PlantainGraphSparqlEngine extends RDFGraphQuery[Plantain] {
+
+ def makeSparqlEngine(graph: Plantain#Graph): SparqlEngine[Plantain, Id] =
+ new PlantainSparqlEngine(graph)
+
+ class PlantainSparqlEngine(graph: Plantain#Graph) extends SparqlEngine[Plantain, Id] {
+
+ def executeSelect(query: Plantain#SelectQuery, bindings: Map[String, Plantain#Node]): Plantain#Solutions = {
+ val tupleExpr = query.getTupleExpr
+ val evaluationStrategy = new EvaluationStrategyImpl(graph)
+ val results = evaluationStrategy.evaluate(tupleExpr, bindings.asSesame)
+ results.toIterator
+ }
+
+ def executeConstruct(query: Plantain#ConstructQuery, bindings: Map[String, Plantain#Node]): Plantain#Graph = {
+ val tupleExpr = query.getTupleExpr
+ val evaluationStrategy = new EvaluationStrategyImpl(graph)
+ val results = evaluationStrategy.evaluate(tupleExpr, bindings.asSesame)
+ val it = results.toIterator
+ var resultGraph = Graph.empty
+ it foreach { bindingSet =>
+ try {
+ val s = bindingSet.getValue("subject").asInstanceOf[Resource]
+ val p = bindingSet.getValue("predicate").asInstanceOf[SesameURI]
+ val o = bindingSet.getValue("object").asInstanceOf[Value]
+ resultGraph += Triple(Node.fromSesame(s), Node.fromSesame(p), Node.fromSesame(o))
+ } catch { case e: Exception => () }
+ }
+ resultGraph
+ }
+
+ def executeAsk(query: Plantain#AskQuery, bindings: Map[String, Plantain#Node]): Boolean = {
+ val tupleExpr = query.getTupleExpr
+ val evaluationStrategy = new EvaluationStrategyImpl(graph)
+ val results = evaluationStrategy.evaluate(tupleExpr, bindings.asSesame)
+ results.hasNext
+ }
+
+ }
+
+
+
+}
+
@@ -0,0 +1,74 @@
+package org.w3.banana.plantain
+
+import org.w3.banana._
+import java.io._
+import org.openrdf.query.resultio.{ QueryResultParseException, QueryResultIO }
+import scala.util._
+import org.openrdf.query._
+import PlantainUtil._
+
+object PlantainQueryResultsReader {
+
+ def apply[T](implicit sesameSparqlSyntax: SesameAnswerInput[T]): SparqlQueryResultsReader[Plantain, T] =
+ new SparqlQueryResultsReader[Plantain, T] {
+
+ def read(in: InputStream, base: String) = {
+ val bytes: Array[Byte] = Iterator.continually(in.read).takeWhile((-1).!=).map(_.toByte).toArray
+ parse(bytes)
+ }
+
+ def parse(bytes: Array[Byte]): Try[Either[Plantain#Solutions, Boolean]] = Try {
+ try {
+ val parsed = QueryResultIO.parse(new ByteArrayInputStream(bytes),
+ sesameSparqlSyntax.booleanFormat)
+ Right(parsed)
+ } catch {
+ case e: QueryResultParseException =>
+ val tupleQueryResult =
+ QueryResultIO.parse(new ByteArrayInputStream(bytes), sesameSparqlSyntax.tupleFormat)
+ Left(tupleQueryResult.toIterator)
+ }
+ }
+
+ def read(reader: Reader, base: String) = {
+ val queri = Iterator.continually(reader.read).takeWhile((-1).!=).map(_.toChar).toArray
+ //it is really horrible to have to turn a nice char array into bytes for parsing!
+ parse(new String(queri).getBytes("UTF-8"))
+ }
+
+ }
+
+ implicit val queryResultsReaderJson: SparqlQueryResultsReader[Plantain, SparqlAnswerJson] =
+ PlantainQueryResultsReader[SparqlAnswerJson]
+
+ implicit val queryResultsReaderXml: SparqlQueryResultsReader[Plantain, SparqlAnswerXml] =
+ PlantainQueryResultsReader[SparqlAnswerXml]
+
+}
+
+/* copied from banana-sesame */
+
+import java.io.InputStream
+import org.openrdf.query.resultio.sparqlxml.SPARQLResultsXMLParserFactory
+import org.openrdf.query.resultio.{ BooleanQueryResultFormat, TupleQueryResultFormat }
+
+trait SesameAnswerInput[T] {
+ def tupleFormat: TupleQueryResultFormat
+ def booleanFormat: BooleanQueryResultFormat
+}
+
+object SesameAnswerInput {
+
+ implicit val Json: SesameAnswerInput[SparqlAnswerJson] =
+ new SesameAnswerInput[SparqlAnswerJson] {
+ val tupleFormat = TupleQueryResultFormat.JSON
+ val booleanFormat = BooleanQueryResultFormat.forMIMEType("application/sparql-results+json")
+ }
+
+ implicit val XML: SesameAnswerInput[SparqlAnswerXml] =
+ new SesameAnswerInput[SparqlAnswerXml] {
+ val tupleFormat = TupleQueryResultFormat.SPARQL
+ val booleanFormat = BooleanQueryResultFormat.forMIMEType("application/sparql-results+xml")
+ }
+
+}
@@ -0,0 +1,61 @@
+package org.w3.banana.plantain
+
+import org.w3.banana._
+import java.io.{ ByteArrayOutputStream, Writer => jWriter }
+import scalax.io._
+import scala.util._
+
+object PlantainSolutionsWriter {
+
+ def apply[T](implicit sesameSparqlSyntax: SesameAnswerOutput[T], _syntax: Syntax[T]) =
+ new SparqlSolutionsWriter[Plantain, T] {
+
+ val syntax = _syntax
+
+ def write[R <: jWriter](answers: Plantain#Solutions, wcr: WriteCharsResource[R], base: String) =
+ Try {
+ val baos = new ByteArrayOutputStream()
+ val sWriter = sesameSparqlSyntax.writer(baos)
+ // sWriter.startQueryResult(answers.getBindingNames)
+ sWriter.startQueryResult(new java.util.ArrayList()) // <- yeah, probably wrong...
+ answers foreach { answer => sWriter.handleSolution(answer) }
+ sWriter.endQueryResult()
+ wcr.write(baos.toString("UTF-8"))
+ }
+
+ }
+
+ implicit val solutionsWriterJson = PlantainSolutionsWriter[SparqlAnswerJson]
+
+ implicit val solutionsWriterXml = PlantainSolutionsWriter[SparqlAnswerXml]
+
+ implicit val writerSelector: SparqlSolutionsWriterSelector[Plantain] =
+ SparqlSolutionWriterSelector[Plantain, SparqlAnswerXml] combineWith
+ SparqlSolutionWriterSelector[Plantain, SparqlAnswerXml]
+
+}
+
+/* copied from banana-sesame */
+
+import java.io.OutputStream
+import org.openrdf.query.resultio.sparqljson.SPARQLResultsJSONWriter
+import org.openrdf.query.resultio.sparqlxml.SPARQLResultsXMLWriter
+import org.openrdf.query.resultio.TupleQueryResultWriter
+
+trait SesameAnswerOutput[SyntaxType] {
+ def writer(outputStream: OutputStream): TupleQueryResultWriter
+}
+
+object SesameAnswerOutput {
+
+ implicit val Json: SesameAnswerOutput[SparqlAnswerJson] =
+ new SesameAnswerOutput[SparqlAnswerJson] {
+ def writer(outputStream: OutputStream) = new SPARQLResultsJSONWriter(outputStream)
+ }
+
+ implicit val XML: SesameAnswerOutput[SparqlAnswerXml] =
+ new SesameAnswerOutput[SparqlAnswerXml] {
+ def writer(outputStream: OutputStream) = new SPARQLResultsXMLWriter(outputStream)
+ }
+
+}
@@ -43,6 +43,6 @@ object PlantainSparqlOps extends SparqlOps[Plantain] {
def varnames(solution: Plantain#Solution): Set[String] = solution.getBindingNames.asScala.toSet
- def solutionIterator(solutions: Plantain#Solutions): Iterable[Plantain#Solution] = solutions
+ def solutionIterator(solutions: Plantain#Solutions): Iterable[Plantain#Solution] = solutions.toIterable
}
@@ -0,0 +1,6 @@
+package org.w3.banana.plantain
+
+import org.w3.banana._
+import Plantain._
+
+class PlantainGraphQueryTest extends RDFGraphQueryTest[Plantain, SparqlAnswerXml]
@@ -0,0 +1,12 @@
+package org.w3.banana.plantain
+
+import org.w3.banana._
+
+//class PlantainSparqlEngineTest extends SparqlEngineTest(
+// SesameStore {
+// val repo = new SailRepository(new MemoryStore)
+//// val d = java.nio.file.Files.createTempDirectory("sesame-")
+//// val repo = new SailRepository((new NativeStore(d.toFile, "spoc,posc")))
+// repo.initialize()
+// repo
+// })
@@ -2390,7 +2390,7 @@
<contact:homePage rdf:resource="http://www.w3.org/2008/webapps/"/>
</org:deliveredBy>
<mat:hasErrata rdf:resource="http://dev.w3.org/2006/waf/widgets-access/errata.html"/>
- <mat:hasTranslations rdf:resource="%20http://www.w3.org/2003/03/Translations/byTechnology?technology=widgets-access"/>
+ <mat:hasTranslations rdf:resource="http://www.w3.org/2003/03/Translations/byTechnology?technology=widgets-access"/>
</REC>
<LastCall rdf:about="http://www.w3.org/TR/2012/WD-WebIDL-20120207/">
@@ -21,7 +21,7 @@ class RDFGraphQueryTest[Rdf <: RDF, SyntaxType]()(
val resource = Resource.fromFile("rdf-test-suite/src/main/resources/new-tr.rdf")
- val graph = reader.read(resource, "http://foo.com") getOrElse sys.error("ouch")
+ val graph = reader.read(resource, "http://foo.com").get
val sparqlEngine = graphQuery.makeSparqlEngine(graph)
"SELECT DISTINCT query in new-tr.rdf " should {

0 comments on commit 077854b

Please sign in to comment.