Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ target/
.cache
.project
.target/
.bsp/

# IntelliJ specific
.idea/
Expand Down
10 changes: 5 additions & 5 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ val buildSettings = Seq (
exportJars := buildExportJars,
updateOptions := updateOptions.value.withCachedResolution(true),
shellPrompt := { state => "sbt [%s]> ".format(Project.extract(state).currentProject.id) },
scalacOptions := Seq("-deprecation", "-unchecked", "-feature", "-target:jvm-1.8", "-language:implicitConversions", "-language:postfixOps", "-Xlint"),
parallelExecution in Test := false,
scalacOptions := Seq("-deprecation", "-unchecked", "-feature", "-release:8", "-language:implicitConversions", "-language:postfixOps", "-Xlint"),
Test / parallelExecution := false,
coverageFailOnMinimum := true,
coverageOutputHTML := true,
coverageOutputXML := true
) ++ Defaults.itSettings
coverageOutputXML := true,
resolvers += Resolver.mavenCentral
)


lazy val project = Project("reactive-sparql", file("."))
.configs(IntegrationTest)
.settings(buildSettings: _*)
.settings(name := "reactive-sparql")
.settings(libraryDependencies ++= `reactive-sparql-dependencies`)
Expand Down
35 changes: 20 additions & 15 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,42 @@ import sbt._

object Version {

val scala = "2.13.3"
val akka = "2.5.29"
val akkaHttp = "10.1.11"
val scala = "2.13.12"
val pekko = "1.0.2"
val pekkoHttp = "1.0.1"
val sslconfig = "0.6.1"
val javaxWsRs = "1.1.1"
val rdf4j = "2.1.6" //"2.3.2"
val logback = "1.2.3"
val scalaTest = "3.0.8"
val fuseki = "3.7.0"
val xmlBind = "2.3.2"
val xerces = "2.12.2"
}


object Dependencies {

val akkaActor = "com.typesafe.akka" %% "akka-actor" % Version.akka
val akkaStream = "com.typesafe.akka" %% "akka-stream" % Version.akka
val akkaHttpCore = "com.typesafe.akka" %% "akka-http-core" % Version.akkaHttp
val akkaHttpSprayJson = "com.typesafe.akka" %% "akka-http-spray-json" % Version.akkaHttp
val akkaSlf4j = "com.typesafe.akka" %% "akka-slf4j" % Version.akka
val pekkoActor = "org.apache.pekko" %% "pekko-actor" % Version.pekko
val pekkoStream = "org.apache.pekko" %% "pekko-stream" % Version.pekko
val pekkoHttpCore = "org.apache.pekko" %% "pekko-http-core" % Version.pekkoHttp
val pekkoHttpSprayJson = "org.apache.pekko" %% "pekko-http-spray-json" % Version.pekkoHttp
val pekkoSlf4j = "org.apache.pekko" %% "pekko-slf4j" % Version.pekko
val sslConfigLib = "com.typesafe" %% "ssl-config-core" % Version.sslconfig
val javaxWsRs = "javax.ws.rs" % "jsr311-api" % Version.javaxWsRs
val logbackClassic = "ch.qos.logback" % "logback-classic" % Version.logback
val rdf4jRuntime = "org.eclipse.rdf4j" % "rdf4j-runtime" % Version.rdf4j
val jakartaXmlBind = "jakarta.xml.bind" % "jakarta.xml.bind-api" % Version.xmlBind
val scalaTest = "org.scalatest" %% "scalatest" % Version.scalaTest % "it,test"
val akkaTestkit = "com.typesafe.akka" %% "akka-testkit" % Version.akka % "it,test"
val akkaStreamTestkit = "com.typesafe.akka" %% "akka-stream-testkit" % Version.akka % "it,test"
val fusekiServer = "org.apache.jena" % "jena-fuseki-server" % Version.fuseki % "it,test"
val xercesImpl = "xerces" % "xercesImpl" % Version.xerces

val scalaTest = "org.scalatest" %% "scalatest" % Version.scalaTest % Test
val pekkoTestkit = "org.apache.pekko" %% "pekko-testkit" % Version.pekko % Test
val pekkoStreamTestkit = "org.apache.pekko" %% "pekko-stream-testkit" % Version.pekko % Test
val fusekiServer = "org.apache.jena" % "jena-fuseki-server" % Version.fuseki % Test

val `reactive-sparql-dependencies` = Seq(
akkaActor, akkaStream, akkaHttpCore, akkaHttpSprayJson, akkaSlf4j,
pekkoActor, pekkoStream, pekkoHttpCore, pekkoHttpSprayJson, pekkoSlf4j,
javaxWsRs, rdf4jRuntime,
logbackClassic, scalaTest, akkaTestkit, akkaStreamTestkit, fusekiServer,
jakartaXmlBind)
logbackClassic, scalaTest, pekkoTestkit, pekkoStreamTestkit, fusekiServer,
jakartaXmlBind, xercesImpl)
}
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.2.8
sbt.version=1.9.9
2 changes: 0 additions & 2 deletions publish.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,3 @@ pomExtra := {
</developer>
</developers>
}

pgpReadOnly := true
2 changes: 1 addition & 1 deletion src/main/scala/ai/agnos/sparql/api/ClientAPIProtocol.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ai.agnos.sparql.api

import akka.http.scaladsl.model.HttpMethod
import org.apache.pekko.http.scaladsl.model.HttpMethod


/**
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/ai/agnos/sparql/api/GraphStoreProtocol.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package ai.agnos.sparql.api
import java.net.URL
import java.nio.file.Path

import akka.http.scaladsl.model.HttpMethod
import akka.http.scaladsl.model.HttpMethods._
import org.apache.pekko.http.scaladsl.model.HttpMethod
import org.apache.pekko.http.scaladsl.model.HttpMethods._
import org.eclipse.rdf4j.model.{IRI, Model}
import org.eclipse.rdf4j.rio.RDFFormat
import org.eclipse.rdf4j.rio.RDFFormat.NTRIPLES
Expand Down
83 changes: 24 additions & 59 deletions src/main/scala/ai/agnos/sparql/api/PrefixMapping.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ai.agnos.sparql.api

import com.sun.org.apache.xerces.internal.util.XMLChar
import org.apache.xerces.util.XMLChar

import scala.util.control.Breaks._

Expand All @@ -22,7 +22,6 @@ object NamespaceConstants {

val RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
val RDFS = "http://www.w3.org/2000/01/rdf-schema#"
val RDFSyntax = "http://www.w3.org/TR/rdf-syntax-grammar#"
val OWL = "http://www.w3.org/2002/07/owl#"
val DC_11 = "http://purl.org/dc/elements/1.1/"
val TERMS = "http://purl.org/dc/terms/"
Expand All @@ -37,15 +36,15 @@ object PrefixMapping {

import NamespaceConstants._

class IllegalPrefixException(prefix : String) extends IllegalArgumentException
private class IllegalPrefixException(prefix : String) extends IllegalArgumentException(prefix)

def none = new PrefixMapping

/**
* A PrefixMapping that contains the "standard" prefixes we know about,
* viz rdf, rdfs, dc, rss, vcard, and owl.
*/
def standard = {
def standard: PrefixMapping = {
val pm = new PrefixMapping
pm.setNsPrefix(PREFIX_RDFS, RDFS)
pm.setNsPrefix(PREFIX_RDF, RDF)
Expand All @@ -55,7 +54,7 @@ object PrefixMapping {
pm
}

def extended = {
def extended: PrefixMapping = {
val pm = standard
pm.setNsPrefix(PREFIX_SKOS, SKOS)
pm.setNsPrefix(PREFIX_FOAF, FOAF)
Expand Down Expand Up @@ -86,7 +85,7 @@ object PrefixMapping {
* @param uri
* @return the index of the first character of the localname
*/
def splitNamespace(uri : String) : Int = {
private def splitNamespace(uri : String) : Int = {

// XML Namespaces 1.0:
// A qname name is NCName ':' NCName
Expand Down Expand Up @@ -115,7 +114,7 @@ object PrefixMapping {
while (i >= 1) {
i -= 1
ch = uri.charAt(i)
if (notNameChar(ch)) break
if (notNameChar(ch)) break()
}

var j = i + 1
Expand Down Expand Up @@ -152,7 +151,7 @@ object PrefixMapping {
// Do a quick test before calling .startsWith
// OLD: if ( uri.charAt(j - 1) == ':' && uri.lastIndexOf(':', j - 2) == -1)
//
if (!(j == 7 && uri.startsWith("mailto:"))) break
if (!(j == 7 && uri.startsWith("mailto:"))) break()
}
}
j
Expand All @@ -161,22 +160,22 @@ object PrefixMapping {
/**
* answer true iff this is not a legal NCName character, ie, is a possible split-point start.
*/
def notNameChar(ch : Char) : Boolean = !XMLChar.isNCName(ch)
private def notNameChar(ch : Char) : Boolean = !XMLChar.isNCName(ch)
}

/**
* Inspired by Jena's PrefixMappingImpl class, this class does more or les the same.
* Inspired by Jena's PrefixMappingImpl class, this class does more or less the same.
*
* See http://svn.apache.org/repos/asf/jena/trunk/jena-core/src/main/java/com/hp/hpl/jena/shared/impl/PrefixMappingImpl.java
*/
class PrefixMapping {

import PrefixMapping._

protected var prefixToURI : Map[String, String] = Map.empty
protected var URItoPrefix : Map[String, String] = Map.empty
private var prefixToURI : Map[String, String] = Map.empty
private var URItoPrefix : Map[String, String] = Map.empty

protected def set(prefix : String, uri : String) {
private def set(prefix : String, uri : String): Unit = {
prefixToURI += prefix -> uri
URItoPrefix += uri -> prefix
}
Expand All @@ -198,7 +197,7 @@ class PrefixMapping {
this
}

protected def regenerateReverseMapping() {
private def regenerateReverseMapping(): Unit = {
URItoPrefix = prefixToURI.map(_.swap)
}

Expand All @@ -209,7 +208,7 @@ class PrefixMapping {
*/
def withDefaultMappings(other : PrefixMapping) : PrefixMapping = {

for ((prefix, uri) other.prefixToURI) {
for ((prefix, uri) <- other.prefixToURI) {
if (getNsPrefixURI(prefix) == null && getNsURIPrefix(uri) == null) {
setNsPrefix(prefix, uri)
}
Expand All @@ -226,9 +225,9 @@ class PrefixMapping {
*
* @param other the Map whose bindings we are to add to this.
*/
def setNsPrefixes(other : Map[String, String]) : PrefixMapping = {
private def setNsPrefixes(other : Map[String, String]) : PrefixMapping = {

for ((prefix, uri) other) {
for ((prefix, uri) <- other) {
setNsPrefix(prefix, uri)
}

Expand All @@ -245,7 +244,7 @@ class PrefixMapping {
/**
* Checks that a prefix is "legal" - it must be a valid XML NCName.
*/
private def checkLegal(prefix : String) {
private def checkLegal(prefix : String): Unit = {
if (prefix.length > 0 && !XMLChar.isValidNCName(prefix))
throw new PrefixMapping.IllegalPrefixException(prefix)
}
Expand Down Expand Up @@ -309,7 +308,7 @@ class PrefixMapping {
* Answer the qname for <code>uri</code> which uses a prefix from this mapping, or null if there isn't one.
* <p>
* Relies on <code>splitNamespace</code> to carve uri into namespace and
* localname components; this ensures that the localname is legal and we just
* localname components; this ensures that the localname is legal, and we just
* have to (reverse-)lookup the namespace in the prefix table.
* </p>
* @see com.hp.hpl.jena.shared.PrefixMapping#qnameFor(java.lang.String)
Expand All @@ -330,52 +329,18 @@ class PrefixMapping {
null
}
else {
prefix + ":" + local
s"$prefix:$local"
}
}

/**
* Compress the URI using the prefix mapping. This version of the code looks through all the maplets and checks each
* candidate prefix URI for being a leading substring of the argument URI. There's probably a much more efficient
* algorithm available, pre-processing the prefix strings into some kind of search table, but for the moment we don't
* need it.
* Compress the URI using the prefix mapping. This version of the code looks through all the maplet
*/
def shortForm(uri : String) : String = {
val (prefix, otherUri) = findMapping(uri, true)
if (prefix == null) {
uri
}
else {
s"${prefix}:${uri.substring(otherUri.length)}"
}
}

def samePrefixMappingAs(other : PrefixMapping) : Boolean = prefixToURI == other.prefixToURI

/**
* Answer a prefixToURI entry in which the value is an initial substring of <code>uri</code>.
* If <code>partial</code> is false, then the value must equal <code>uri</code>.
*
* Does a linear search of the entire prefixToURI, so not terribly efficient for large maps.
*
* @param uri the value to search for
* @param partial true if the match can be any leading substring, false for exact match
* @return some entry (k, v) such that uri starts with v [equal for partial=false]
*/
private def findMapping(uri : String, partial : Boolean) : (String, String) = {
for ((prefix, otherUri) ← prefixToURI) {
if (uri.startsWith(otherUri) && (partial || otherUri.length == uri.length)) {
return (prefix, otherUri)
}
}
(null, null)
def sparql : String = {
pairs.map {
case (key, value) => s"PREFIX ${key}: <${value}>"
}.mkString("\n", "\n", "\n")
}

private def pairs = prefixToURI.toList sortBy { _._1 }

def sparql : String = {
pairs map {
case (key, value) ⇒ s"PREFIX ${key}: <${value}>"
} mkString ("\n", "\n", "\n")
}
}
6 changes: 3 additions & 3 deletions src/main/scala/ai/agnos/sparql/api/SparqlClientProtocol.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package ai.agnos.sparql.api

import akka.actor.ActorSystem
import akka.http.scaladsl.model.{StatusCode, StatusCodes}
import akka.http.scaladsl.model.HttpMethods._
import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.http.scaladsl.model.{StatusCode, StatusCodes}
import org.apache.pekko.http.scaladsl.model.HttpMethods._


trait SparqlClientProtocol extends ClientAPIProtocol
Expand Down
5 changes: 3 additions & 2 deletions src/main/scala/ai/agnos/sparql/api/SparqlConstruct.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package ai.agnos.sparql.api


import akka.http.scaladsl.model.{HttpMethod, HttpMethods}
import org.apache.pekko.http.scaladsl.model.{HttpMethod, HttpMethods}
import org.eclipse.rdf4j.model.{BNode, IRI, Literal, Value}


Expand Down Expand Up @@ -120,7 +120,8 @@ abstract class SparqlConstruct()(
case literal: Literal =>
val tpe = literal.getDatatype
s"'${literal.stringValue()}'^^${pm.getNsURIPrefix(tpe.getNamespace)}:${tpe.getLocalName}"
case bn: BNode => throw new IllegalArgumentException("Should not use Blank Node as query parameter")
case _: BNode => throw new IllegalArgumentException("Should not use Blank Node as query parameter")
case _ => throw new IllegalArgumentException(s"Unsupported value type ${value.getClass.getName}")
}
}
}
6 changes: 3 additions & 3 deletions src/main/scala/ai/agnos/sparql/api/SparqlQuery.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package ai.agnos.sparql.api

import akka.http.scaladsl.model._
import akka.stream.scaladsl.Source
import akka.util.ByteString
import org.apache.pekko.http.scaladsl.model._
import org.apache.pekko.stream.scaladsl.Source
import org.apache.pekko.util.ByteString
import org.eclipse.rdf4j.model.{IRI, Value}
import ai.agnos.sparql.stream.client.SparqlClientConstants._
import ai.agnos.sparql.util.SparqlQueryStringConverter
Expand Down
3 changes: 1 addition & 2 deletions src/main/scala/ai/agnos/sparql/api/SparqlStatement.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package ai.agnos.sparql.api

import akka.http.scaladsl.model._
import org.apache.pekko.http.scaladsl.model._

import scala.concurrent.duration._
import scala.language.postfixOps


/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/ai/agnos/sparql/api/SparqlUpdate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package ai.agnos.sparql.api

import java.text.SimpleDateFormat

import akka.http.scaladsl.model.{HttpMethod, HttpMethods}
import org.apache.pekko.http.scaladsl.model.{HttpMethod, HttpMethods}

object SparqlUpdate {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ai.agnos.sparql.api.QuerySolution
/**
* A helper mapper that delegates mapping to a specified function.
*/
class DelegatingSolutionMapper[T] private (mapper : QuerySolution T)
class DelegatingSolutionMapper[T] private (mapper : QuerySolution => T)
extends SolutionMapper[T] {

def map(querySolution : QuerySolution) : T = {
Expand All @@ -15,5 +15,5 @@ class DelegatingSolutionMapper[T] private (mapper : QuerySolution ⇒ T)
}

object DelegatingSolutionMapper {
def apply[T](mapper : QuerySolution T) = new DelegatingSolutionMapper[T](mapper)
def apply[T](mapper : QuerySolution => T) = new DelegatingSolutionMapper[T](mapper)
}
Loading