Giter Club home page Giter Club logo

banana-rdf's Introduction

banana-rdf

Build Status Gitter

The current published version 0.8.6, compiled with scala 2.13.6, is to be found on Maven Central under groupId net/bblfish/rdf/.

val banana = (name: String) => "net.bblfish.rdf" %% name % "0.8.6" excludeAll (ExclusionRule(organization = "org.scala-stm"))

//choose the packages you need for your dependencies
val bananaDeps = Seq("banana", "banana-rdf", "banana-rdf4j").map(banana)

Snapshot releases can be found on sonatype.org. To use these you will need at add the sonatype resolver to your sbt build:

resolvers += Resolver.sonatypeRepo("snapshots")

A Scala3 version is being developed on the scala-3 branch of this repository.

An RDF library in Scala

banana-rdf is a library for RDF, SPARQL and Linked Data technologies in Scala.

It can be used with existing libraries without any added cost. There is no wrapping involved: you manipulate directly the real objects. We currently support Jena, RDF4J and Plantain, a pure Scala implementation.

Features

banana-rdf emphasizes type-safety and immutability, so it can come with some cost when the underlying implementation is very mutable (I'm looking at you, Jena and RDF4J). We try to keep a clear distinction between the core concepts and the enhanced syntax that Scala can give us.

RDF itself is defined as a record of types. Implementations just have to plug their own types. And because types alone are not enough, we introduce the RDFOps typeclass, which defines the mandatory operations that an RDF implementation must implement. SparqlOps does the same for SPARQL.

With banana-rdf, you get Diesel, a nice DSL to build and navigate within pointed graphs (graphs with a pointer to an inner node). You also get an abstraction for graph stores (GraphStore), which do not have to be SPARQL engines (SparqlEngine). Of course, you can serialize and deserialize most of the RDF syntaxes as well as JSON-LD (RDFa will come soon).

banana-rdf introduces the concept of binders, which let you bridge the Scala and RDF worlds. Most of the common datastructures are already available, and you can even map your own classes. Unlike usual ORM techniques, this does not rely on annotation or reflection.

Until we write thorough documentation, the best place to understand what you can do is to go through the test suite.

How to start geeking

To get going with banana-rdf and get a feel for how to use it the easiest and fastest way may well be to use it directly in the Ammonite shell as explained in the Scripting with Ammonite wiki page.

It always helps to have the code available, as there are a lot of useful examples in the test suite. You only need a recent version of Java, that's all:

$ git clone [email protected]:w3c/banana-rdf.git
$ cd banana-rdf
$ sbt

It's also easy to just build specific target platforms:

$ sbt +banana_js/test    # for javascript only 
$ sbt +banana_jvm/test   # for jvm only

( note: scala-js compilation uses more memory. see travis.yml )

IDE Setup

banana-rdf works with both eclipse and IntelliJ IDEA.

global.sbt

Independent of your preferred IDE, optionally the add the following line to ~/.sbt/0.13/global.sbt to prevent the generation of empty source directories:

    unmanagedSourceDirectories in Compile ~= { _.filter(_.exists) }

Eclipse

Eclipse should work "out of the box" with the addition of the following global settings:

In ~/.sbt/0.13/global.sbt:

    unmanagedSourceDirectories in Compile ~= { _.filter(_.exists) }

In ~/.sbt/0.13/plugins/build.sbt

    addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.5.0")

To generate eclipse project files, just run the command:

$ sbt eclipse

IntelliJ IDEA

IntelliJ IDEA works out of the box since 2016.

Community

For discussions that don't fit in the issues tracker, you may try either

Code of Conduct

Banana-RDF contributors all agree to follow the W3C Code of Ethics and Professional Conduct.

If you want to take action, feel free to contact Alexandre Bertails [email protected]. You can also contact W3C Staff as explained in W3C Procedures.

Licence

This source code is made available under the W3C Licence. This is a business friendly license.

banana-rdf's People

Contributors

ahoy-jon avatar alistair-johnson avatar antoniogarrote avatar antonkulaga avatar bblfish avatar betehess avatar deniak avatar fernandomora avatar folone avatar ghxiao avatar intracer avatar jiemakel avatar jkransen avatar jmvanel avatar kendall avatar maatary avatar ngbinh avatar nicolasrouquette avatar ovstetun avatar perspectivet avatar philleach avatar stain avatar tgambet avatar travisbrown avatar tulionaja avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

banana-rdf's Issues

RDFReader is missing encoding field

The RDFReader class is built around a method def read(is: InputStream, base: String): Try[Rdf#Graph] which takes a stream of bytes, but does not allow one to specify the encoding of the bytes. This is missing from the signature.

trait RDFReader[Rdf <: RDF, +S] {

  def syntax: Syntax[S]

  def read(is: InputStream, base: String): Try[Rdf#Graph]

  def read(input: String, base: String): Try[Rdf#Graph] = {
    val is = new ByteArrayInputStream(input.getBytes("UTF-8"))
    read(is, base)
  }

}

write any documentation

Until we write thorough documentation, the best place to understand what you can do is to go through the test suite.

I looked at tests and from them it is absolutely unclear how to use it with Sesame (I see only declarations of classnames there) or any other persistent RDF store. Could you write at least small getting started guide with typical things like: opening sesame database, loading into bananrdf, adding or reading some quads, saving the result?

async, sync and blocking

Stop this non-productive and annoying "Blocking" keyword appearing there and there.

This does not help at all going through the API.

ACTION: drop all "Blocking" and "Sync" from the class names.

We'll consider revise this convention when we'll have real non-blocking alternatives at the banana-rdf level.

prefix and base in SPARQL

Currently prefix and base seem to be mixed up, as shown by this exemple from SparqlGraphTest.scala

val base = Prefix[Rdf]("", "http://www.w3.org/2001/02pd/rec54#")
val rdf = RDFPrefix[Rdf]
val contact = Prefix[Rdf]("contact", "http://www.w3.org/2000/10/swap/pim/contact#")

val query2 = ConstructQuery("""
                           |CONSTRUCT {
                           |  ?thing :editor ?ed .
                           |  ?ed contact:fullName ?name .
                           |}  WHERE {
                           |  ?thing :editor ?ed .
                           |  ?ed contact:fullName ?name
                           |}""".stripMargin, base, rdf, contact)

This is very unintuitive.

  • N3 the empty prefix is the prefix you want to use the most often, not the base.
  • setting prefixes is something that makes writing SPARQL in scala code easy, but the other use case is that one receives a Query from the web with no base, and there setting the base is the only thing one wants to do.
  • when writing queries in Scala one should not need to write out the prefixes. They should be added automatically.
  • If one receives an Option[URI] for a base one then has to write weird code such as base.map(ops.UpdateQuery(query,_)).getOrElse(ops.UpdateQuery(query)) or Query(base.map(b=>s"base $b \n").getOrElse("")+query)

I suggest changing the signatures to accommodate both cases to the (something like) the following

def SelectQuery(query: String, base: Option[Rdf#URI])(implicit prefixes: Seq[Prefix[Rdf]]): Rdf#SelectQuery 
def ConstructQuery(query: String, base: Option[Rdf#URI])(implicit prefixes: Seq[Prefix[Rdf]]): Rdf#ConstructQuery 
...

Because of name clashes with the abstract methods of SparqlOps[Rdf <: RDF] traits one cannot give a default value to the base.

document binder examples with graphs

The binder examples in ObjectExamples map from scala to rdf graphs and back, but one does not see the graphs generated. So it is not clear for example if

val otherNames = set[String](foaf("otherNames"))

Is mapping to the graph

:p foaf:person "Joe","Joey" .

or to

:p foaf:person [ rdf:Collection;
                         rdf:first "Joe";
                         rdf:second "Joey" ].

( or whatever the correct rdf for a collection is (I did not look it up))

ldp: output in style of rww.io

rww.io has like data.fm a certain way of describing an LDPC which we should perhaps follow, in order to make tools like rww-play interact with other JS scripts that can read this data:

$ cwm http://stample.rww.io/2013/
    @prefix : <http://www.w3.org/ns/ldp#> .
    @prefix stat: <http://www.w3.org/ns/posix/stat#> .

    <>     a :Container,
                stat:Directory;
         <http://www.w3.org/2000/01/rdf-schema#member> <card.ttl>,
                <test>;
         :membershipObject :MemberSubject;
         :membershipPredicate <http://www.w3.org/2000/01/rdf-schema#member>;
         :membershipSubject <>;
         stat:mtime 1379339023;
         stat:size 4096 .

    <?p=1>     a :Page;
         :nextPage ();
         :pageOf <> .

    <card.ttl>     a <http://www.w3.org/2000/01/rdf-schema#Resource>;
         stat:mtime 1378826500;
         stat:size 147 .

    <test>     a <http://www.w3.org/2000/01/rdf-schema#Resource>;
         stat:mtime 1379339055;
         stat:size 114 .

read-write-web/rww-play#4

It may be worth otherwise making the output configurable.

relative URIs

I was thinking of creating named graphs with relative URIs, just because it is easy from an HTTP request with a path, to find the named graph for that path, though it is perhaps not necessary to know the full URI.
So I was not sure if this would work or not.

On the console I was able to create a relative URI in Jena but not in Sesame.

> project banana-jena
scala>:history 3
2467  import org.w3.banana.jena._
2468  import Jena._
2469  import ops._

scala>  URI("/profile/hjs#me")
res0: org.w3.banana.jena.Jena#URI = /profile/hjs#me

scala> URI("http://profile.example")
res1: org.w3.banana.jena.Jena#URI = http://profile.example

scala> import diesel._
import diesel._

scala> res0.fragment
res3: Option[String] = Some(me)

scala> res0.resolveAgainst(res1)
res4: org.w3.banana.jena.Jena#URI = http://profile.example/profile/hjs#me

scala> import com.hp.hpl.jena.sparql.core._
import com.hp.hpl.jena.sparql.core._

scala> val jenaStore = JenaStore(DatasetGraphFactory.createMem())
log4j:WARN No appenders could be found for logger (com.hp.hpl.jena.sparql.mgt.ARQMgt).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
jenaStore: org.w3.banana.jena.JenaStore = org.w3.banana.jena.JenaStore@643293ae

scala> import diesel._
import diesel._

scala> val graph = (
     |   bnode("betehess")
     |     -- foaf.name ->- "Alexandre".lang("fr")
     |     -- foaf.title ->- "Mr"
     |   ).graph
graph: org.w3.banana.jena.Jena#Graph = UnionGraphs(List(GraphAsIterable(WrappedArray(betehess @http://xmlns.com/foaf/0.1/name "Alexandre"@fr)), GraphAsIterable(WrappedArray(betehess @http://xmlns.com/foaf/0.1/title "Mr"^^http://www.w3.org/2001/XMLSchema#string))))

scala> import org.w3.banana._
import org.w3.banana._

scala> jenaStore.execute {
     |       Command.append[Jena](res0,graphToIterable(graph))
     | }

scala> res3.getOrFail()

scala> jenaStore.getGraph(res0)
res8: org.w3.banana.jena.ImmutableJenaGraph = BareJenaGraph( {betehess @http://xmlns.com/foaf/0.1/name "Alexandre"@fr; betehess @http://xmlns.com/foaf/0.1/title "Mr"^^http://www.w3.org/2001/XMLSchema#string})

So I am able to create a relative URI, work with it, and create a graph and fetch it at that relative URI.

On the other hand with Sesame, I can't get to the point of creating the relative URI.

 > project banana-sesame
scala> :history 3
2500  import org.w3.banana.sesame._
2501  import Sesame._
2502  import ops.
scala> URI("/profile/hjs#me")
java.lang.IllegalArgumentException: Not a valid (absolute) URI: /profile/hjs#me
    at org.openrdf.model.impl.URIImpl.setURIString(URIImpl.java:68)
    at org.openrdf.model.impl.URIImpl.<init>(URIImpl.java:57)

which is the correct behavior?

SparqlOps.Query should take an optional BaseURI

It is possible to make queries with relative URIs

In Jena's QueryFactory

    static public Query create(String queryString, String baseURI)

in Sesame `QueryParser

    public ParsedQuery parseQuery(String queryStr, String baseURI)

But banana SparqlOps only has

 def Query(query: String): Validation[Exception, Rdf#Query]

it should have

 def Query(query: String, base: Option[URI] = None): Validation[Exception, Rdf#Query]

Of course relative URLs are defined in the SPARQL spec

ldp: pre-conditions and post conditions

Certain types of resources require pre-condition and probably post-conditions.
So for example certain types of ldp:Container may only accept certain types of POSTs. It should therefore be possible to tie a LDPR type to a number of preconditions for each type of relevant action. It would then be possible to
associate such a type to a some scala object that could insert a FreeMonad Command into the FreeMonad stack. The ldp store could be configured with a number of relations relating types of InformationResources to such scala objects.

ping:EventContainer ldp:conditions java:PingConditions .

The advantage of this is that these pre/post-conditions could be applied wherever such a container was placed.

Sesame : RdfGraphQueryTest Failed

[info] - Alexandre Bertails must appear as an editor in new-tr.rdf *** FAILED ***
[info]   query Slice ( limit=1 )
[info]    Join
[info]       StatementPattern
[info]          Var (name=thing)
[info]          Var (name=-const-1, value=http://www.w3.org/2001/02pd/rec54#editor, anonymous)
[info]          Var (name=ed)
[info]       StatementPattern
[info]          Var (name=ed)
[info]          Var (name=-const-2, value=http://www.w3.org/2000/10/swap/pim/contact#fullName, anonymous)
[info]          Var (name=-const-3, value="Alexandre Bertails", anonymous)
[info]  must return true (RDFGraphQueryTest.scala:136)

compilation: bad symbolic reference

Any idea why this error keeps coming up:

[error] bad symbolic reference. A signature in package.class refers to type BananaRDFWriterSelector
[error] in package org.w3.banana which is not available.
[error] It may be completely missing from the current classpath, or the version on
[error] the classpath might be incompatible with the version used when compiling package.class.
[error] bad symbolic reference. A signature in package.class refers to type BananaSparqlSolutionWriterSelector
[error] in package org.w3.banana which is not available.
[error] It may be completely missing from the current classpath, or the version on
[error] the classpath might be incompatible with the version used when compiling package.class.
[info] Resolving org.openrdf.sesame#sesame-rio-rdfxml;2.6.10 ...

I can get rid of it by running clean in sbt but then I need to do that everytime I restart sbt, which slows things down quite a lot.

do not make use of enhanced syntax

... in the code itself (especially Diesel).

Instead, call the bare functions (like the ones in RDFOperations) and make the calls to the typeclass instances explicit.

LinkedData example doesn't terminate

This example doesn't terminate. It prints "End" and doesn't stop. On the other hand, a System.exit(0) at the end works fine.

import org.w3.banana.jena.JenaOperations.URI
import org.w3.banana.jena._
import org.w3.banana._
import org.w3.linkeddata._


object SomeRdfApp extends App {

  val ld = LinkedData.inMemoryImpl(JenaOperations, JenaGraphTraversal, JenaRDFUtils, JenaReaderFactory)

  import ld._


  val cert = Prefix("cert", "http://www.w3.org/ns/auth/cert#", JenaOperations)
  val foaf = Prefix("foaf", "http://xmlns.com/foaf/0.1/", JenaOperations)

  val resultLD = for {
    bblfish โ† ld.goto(URI("http://bblfish.net/people/henry/card#me"))
    person โ† bblfish.follow(foaf("knows"))
    name โ† person.follow(foaf("firstName"))
  } yield (name)

  val result = resultLD.timbl()

  result.map(_.map(println(_)))

  println("End")


}

Inttroduce new parent subtype for URI and BNode.

Maybe it make sense to introduce new type - URILike (not sure about the name). And then

  type URILike <: Node
  type URI <: URILike
  type BNode <: URILike

Because now Literal can be used as a pointer in a pointed graph, or Triple subject also can be of Literal type. There is corresponding type in the Sesame API - org.openrdf.model.Resource, but it seems there is nothing similar on the Jena side.
What do you think?

bind SPARQL query variables to constants

Often one wants to compile a SPARQL query, and then bind variables specifically for each request.
For example in the following WebID query one would like to replace the ?webid variable
with a new one for each query.

 val query = sparqlOps.SelectQuery("""
      PREFIX : <http://www.w3.org/ns/auth/cert#>
      SELECT ?m ?e
      WHERE {
          ?webid :key [ :modulus ?m ;
                         :exponent ?e ].
      }""")

For example in Jena this can be done with:

 val query = QueryFactory.create("""
      PREFIX : <http://www.w3.org/ns/auth/cert#>
      SELECT ?m ?e
      WHERE {
          ?webid :key [ :modulus ?m ;
                        :exponent ?e ].
      }""")

 val initialBinding = new QuerySolutionMap();
 initialBinding.add("webid", model.createResource(webid.url.toString))
 val qe: QueryExecution = QueryExecutionFactory.create(query, model, initialBinding)
 val resultset = qe.execSelect()
 ...

Something similar can be done in Sesame.

It would be good to allow this to be expressed within Banana.

document binder examples with graphs

The binder examples in ObjectExamples map from scala to rdf graphs and back, but one does not see the graphs generated. So it is not clear for example if

val otherNames = set[String](foaf("otherNames"))

Is mapping to the graph

:p foaf:otherNames "Joe","Joey" .

or to

:p foaf:person [ rdf:Collection;
                         rdf:first "Joe";
                         rdf:second "Joey" ].

( or whatever the correct rdf for a collection is (I did not look it up))
(( In any case no need to use foaf:otherNames, foaf:name would have done the job :-)

URI's are not escaped

URIs built with PrefixBuilder from strings containing spaces and other URI-invalid characters are invalid. Everything works OK until one outputs a graph into Turtle file etc. (using writers), which is, obviously, invalid. Example:

<http://example.com/Diabetes Res. Clin. Pract.> <http://example.com/abbr> "Diabetes Res. Clin. Pract."^^<http://www.w3.org/2001/XMLSchema#string> .

It's quite unclear whether PrefixBuilder's apply should get an escaped URI part as its argument, so this is possibly not a bug, but an enhancement.

I'm using Sesame as an implementation. In its source code I've found a comment where it's explicitly said that the URI should already be escaped. (http://grepcode.com/file/repo1.maven.org/maven2/org.openrdf.sesame/sesame-model/2.7.7/org/openrdf/model/impl/URIImpl.java/)

So, should I escape URI parts manually, or it should be done inside BananaRDF?

scala-js compilation option for banana

scala-js allows one to compile Scala into JS. They have just release version 0.1 as of December 2013. They are aiming to make akka useable with scala-js. This would allow one to write banana code for the client and the server, and have a nice working environment.

This may require the following:

  • a pure scala implementation of banana-rdf. We used to have Plantain that was very close to this (see the ldp branch for an improved version of Plantain )
  • a wrapper for communicating with a JS store such as rdf-store

If one could just compile this in JS this could be used as a test case by the rdfstore-js people of the power of their compiler.

backward traversal of PointedGraph

Often one wants to search backwards in pointed graphs. For forward searche there is /
for backward search we could have
This works, but it could be added to lib

implicit class GraphW(pointed: PointedGraph[Rdf]) extends AnyVal {
    import pointed.graph
    def pointer: Rdf#Node = pointed.pointer

    def \(p: Rdf#URI): PointedGraphs = {
      val nodes = getSubjects(graph, p, pointer)
      new PointedGraphs(nodes, graph)
    }
  }

OOM and infinite parsing for title in LinkHeaderParser

Hello

  val lhp = new LinkHeaderParser

  "test OK 1" in { lhp.parse("""<http://example.org/>; rel="start http://example.net/relation/other"""") }
  "test OK 2" in { lhp.parse("""<http://example.org/>; rel="meta"; """) }
  "test OK 3" in { lhp.parse("""<http://example.org/>; rel="meta"; title*=UTF-8'de'letztes%20Kapitel""") }
  "test NOT OK 4" in { lhp.parse("""<http://example.org/>; rel="meta"; title="Metadata File"""") }
  "test NOT OK 5" in { lhp.parse("""<http://id.myopenlink.net/DAV/VAD/wa/RDFData/All/iid (1030025).rdf,meta>; rel="meta"; title="Metadata File"""") }

On the last 2 cases the parser never returns, consume all the CPU and JVM heap.
The last case was the case encountered in a real life situation while trying to parse link headers of a real foaf profile.

No API for default graph

Most of underlying Store have the default graph concept, but the API to manipulate the defaultGraph doesn't exist.

raise consistent exceptions on parsing error

When trying to read an unvalid turtle file with Plantain I get the following exception:

Caused by: MainException: class org.openrdf.rio.RDFParseException(Expected '.', found '<' [line 24])
    at scalax.io.ResourceContext$class.errorHandler(ResourceContext.scala:58)
    at scalax.io.Resource$$anon$4.errorHandler(Resource.scala:544)
    at scalax.io.Resource$class.liftedTree2$1(Resource.scala:200)
    at scalax.io.Resource$class.acquireFor(Resource.scala:199)
    at scalax.io.managed.ReaderResource.acquireFor(ReaderResource.scala:9)
    at resource.ManagedResourceOperations$class.acquireAndGet(ManagedResourceOperations.scala:25)
    at scalax.io.managed.ReaderResource.acquireAndGet(ReaderResource.scala:9)
    at org.w3.banana.plantain.PlantainTurtleReader$$anonfun$read$1.apply(PlantainRDFReader.scala:32)
    at org.w3.banana.plantain.PlantainTurtleReader$$anonfun$read$1.apply(PlantainRDFReader.scala:32)
    at scala.util.Try$.apply(Try.scala:161)
    at org.w3.banana.plantain.PlantainTurtleReader$.read(PlantainRDFReader.scala:31)
    at org.w3.banana.RDFReader$class.read(RDFReader.scala:20)
    at org.w3.banana.plantain.PlantainTurtleReader$.read(PlantainRDFReader.scala:27)
    at rww.ldp.PlantainLDPRActor$$anon$1.load(PlantainLDPRActor.scala:75)
    ... 28 more
Caused by: org.openrdf.rio.RDFParseException: Expected '.', found '<' [line 24]
    at org.openrdf.rio.helpers.RDFParserBase.reportFatalError(RDFParserBase.java:691)
    at org.openrdf.rio.turtle.TurtleParser.reportFatalError(TurtleParser.java:1208)
    at org.openrdf.rio.turtle.TurtleParser.verifyCharacterOrFail(TurtleParser.java:1089)
    at org.openrdf.rio.turtle.TurtleParser.parseStatement(TurtleParser.java:246)
    at org.openrdf.rio.turtle.TurtleParser.parse(TurtleParser.java:201)
    at org.w3.banana.plantain.PlantainTurtleReader$$anonfun$read$1$$anonfun$apply$1.apply(PlantainRDFReader.scala:36)
    at org.w3.banana.plantain.PlantainTurtleReader$$anonfun$read$1$$anonfun$apply$1.apply(PlantainRDFReader.scala:32)
    at scalax.io.Resource$class.liftedTree1$1(Resource.scala:192)
    at scalax.io.Resource$class.acquireFor(Resource.scala:192)
    ... 38 more

This is problematic to have to handle org.openrdf.rio.RDFParseException which is a dependency exception.
And this is also more problematic that this exception is wrapped in a generic exception, making error handling even more difficult.

I think Banana should rather catch these exceptions and raise a custom banana exception that will be constant for all supported Rdf implementations

Why Prefix depends on RDFOperations[Rdf] ?

Currently, when we use prefix, we have to provide an RDFOperations :

import org.w3.banana.Prefix
import org.w3.banana.jena.JenaOperations

val cert = Prefix("cert", "http://www.w3.org/ns/auth/cert#", JenaOperations)
val foaf = Prefix("foaf", "http://xmlns.com/foaf/0.1/", JenaOperations)

Why can't we drop the RDFOpertaions argument ? (no curring, no implicit, just dropped dependency)

import org.w3.banana.Prefix

val cert = Prefix("cert", "http://www.w3.org/ns/auth/cert#")
val foaf = Prefix("foaf", "http://xmlns.com/foaf/0.1/")

RDFOps.diff

I've quickly added RDFOps.diff, needed for LDP PATCH. I've only provided the implementation for banana-jena so it's missing for banana-sesame. Tests are also missing.

Sesame 2.7 is out

I guess there is no need to depend on the beta version of Sesame 2.7, right?

Banana-n3-test-suite doesn't compile

> project banana-n3-test-suite
[info] Set current project to banana-n3-test-suite (in build file:/Users/Jon/Projects/banana-rdf/)
> compile
[info] Compiling 4 Scala sources to /Users/Jon/Projects/banana-rdf/n3-test-suite/target/scala-2.9.1/classes...
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:27: type mismatch;
[error]  found   : org.w3.banana.RDFOperations[Rdf]
[error]  required: org.w3.banana.Diesel[Rdf]
[error]   val serializer = new Serializer[Rdf](ops)
[error]                                        ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:39: type mismatch;
[error]  found   : org.w3.banana.RDFOperations[Rdf]
[error]  required: org.w3.banana.Diesel[Rdf]
[error]       ops,
[error]       ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:224: not found: value TypedLiteral
[error]   def genPlainLiteral = for (str <- genUnicodeStr) yield TypedLiteral(str)
[error]                                                          ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:56: missing parameter type for expanded function
[error] The argument types of an anonymous function must be fully known. (SLS 8.5)
[error] Expected type was: ? => ?
[error]    property("Plainliteral") = forAll(genPlainLiteral) { case literal @ TypedLiteral(lit, tpe) =>
[error]                                                       ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:228: not found: value LangLiteral
[error]                             lang <- genLangStr) yield LangLiteral(str, Lang(lang))
[error]                                                       ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:65: missing parameter type for expanded function
[error] The argument types of an anonymous function must be fully known. (SLS 8.5)
[error] Expected type was: ? => ?
[error]    property("langLiteral") = forAll(genLangLiteral) { case tst @ LangLiteral(lit, Lang(lang)) =>
[error]                                                     ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:86: not found: type URI
[error]            (parsedUri.get.isInstanceOf[URI] :| "not an URI") &&
[error]                                        ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:222: not found: value URI
[error]   def genURI = Gen.oneOf(uris).map( u => URI(u) )
[error]                                          ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:226: not found: value TypedLiteral
[error]                              tpe <- genURI) yield TypedLiteral(str, tpe)
[error]                                                   ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:93: missing parameter type for expanded function
[error] The argument types of an anonymous function must be fully known. (SLS 8.5)
[error] Expected type was: ? => ?
[error]   property("dataTypedLiteral") = forAll(genTypedLiteral) { case lit @ TypedLiteral(str, URI(uri)) =>
[error]                                                          ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:229: not found: value BNode
[error]   def genBnode = Gen.identifier.map(id => BNode(id))
[error]                                           ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:105: type mismatch;
[error]  found   : tr.type (with underlying type (Nothing, Nothing, Nothing))
[error]  required: Rdf#Triple
[error]     val statement = tripleAsN3(tr)
[error]                                ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:152: type Triple takes type parameters
[error]   def generateDoc(graph: List[Triple]) = {
[error]                               ^
[warn] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:155: non variable type-argument A in type pattern (A, B, C) is unchecked since it is eliminated by erasure
[warn]       for (Triple(s, r, o) <- graph) {
[warn]                  ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:157: type mismatch;
[error]  found   : s.type (with underlying type A)
[error]  required: Rdf#Node
[error]         b.append(nodeAsN3(s))
[error]                           ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:159: type mismatch;
[error]  found   : r.type (with underlying type B)
[error]  required: Rdf#Node
[error]         b.append(nodeAsN3(r))
[error]                           ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:161: type mismatch;
[error]  found   : o.type (with underlying type C)
[error]  required: Rdf#Node
[error]         b.append(nodeAsN3(o))
[error]                           ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/NTriplesSpec.scala:143: type Triple takes type parameters
[error]       val resSet = res.user.queue.map(_.asInstanceOf[Triple]).toSet
[error]                                                      ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleParserTest.scala:38: not found: type GraphIsomorphism
[error]   val morpheus: GraphIsomorphism[Rdf2]
[error]                 ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleParserTest.scala:65: graphAsIterable is not a member of ops2
[error]       import ops2.graphAsIterable
[error]              ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleParserTest.scala:66: not found: value graphAsIterable
[error]       val referenceAsSet = graphAsIterable(referenceResult).toIterable.toSet
[error]                            ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleParserTest.scala:67: not found: value graphAsIterable
[error]       val resultAsSet = graphAsIterable(gAsOther).toIterable.toSet
[error]                         ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:24: not found: type GraphIsomorphism
[error]                              val isomorphism: GraphIsomorphism[Rdf]) extends Properties("Turtle") {
[error]                                               ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:33: type mismatch;
[error]  found   : org.w3.banana.RDFOperations[Rdf]
[error]  required: org.w3.banana.Diesel[?]
[error]   val serializer = new Serializer(ops)
[error]                                   ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:37: type mismatch;
[error]  found   : org.w3.banana.RDFOperations[Rdf]
[error]  required: org.w3.banana.Diesel[?]
[error]       ops,
[error]       ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:223: not found: value URI
[error]       val t=Triple(URI("http://bblfish.net/#hjs"),URI("http://xmlns.com/foaf/0.1/knows"), URI("http://www.w3.org/People/Berners-Lee/card#i"))
[error]                    ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:236: not found: value URI
[error]   val hjs=URI("http://bblfish.net/#hjs")
[error]           ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:237: not found: value URI
[error]   val timbl = URI("http://www.w3.org/People/Berners-Lee/card#i")
[error]               ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:238: not found: value URI
[error]   val presbrey = URI("http://presbrey.mit.edu/foaf#presbrey")
[error]                  ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:241: not found: value URI
[error]   val t3=Triple(hjs,foaf.mbox, URI("mailto:[email protected]"))
[error]                                ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:242: not found: value LangLiteral
[error]   val t4=Triple(hjs,foaf.name, LangLiteral("Henry Story",Lang("en")))
[error]                                ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:243: not found: value TypedLiteral
[error]   val t5=Triple(hjs,foaf.name, TypedLiteral("bblfish"))
[error]                                ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:246: not found: value Graph
[error]     val g= Graph(t,t2)
[error]            ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:258: not found: value Graph
[error]     val g= Graph(t,t2,t3)
[error]            ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:271: not found: value Graph
[error]     val g= Graph(t,t2,t3,t4,t5)
[error]            ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:285: not found: value Graph
[error]     val g= Graph(t,t2,t3,t4,t5)
[error]            ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:315: not found: value URI
[error]   val bobDylan=URI("http://dbpedia.org/resource/Bob_Dylan")
[error]                ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:316: not found: value URI
[error]   val t6= Triple(bobDylan,URI("http://purl.org/dc/elements/1.1/created"),LangLiteral(lit1,Lang("en-us-poetic2")))
[error]                           ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:316: not found: value LangLiteral
[error]   val t6= Triple(bobDylan,URI("http://purl.org/dc/elements/1.1/created"),LangLiteral(lit1,Lang("en-us-poetic2")))
[error]                                                                          ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:317: not found: value LangLiteral
[error]   val t7= Triple(bobDylan,foaf.name,LangLiteral("Bob Dylan",Lang("en")))
[error]                                     ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:320: not found: value Graph
[error]     val g= Graph(t6,t7)
[error]            ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:341: not found: value Graph
[error]     val g= Graph(t6,t7)
[error]            ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:363: not found: value URI
[error]   val hasCats = URI("http://cats.edu/ont/has")
[error]                 ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:365: not found: value TypedLiteral
[error]   val t8 = Triple(hjs,hasCats,TypedLiteral("2",xsd.integer))
[error]                               ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:366: not found: value TypedLiteral
[error]   val t8bis = Triple(hjs,hasCats,TypedLiteral("3.2",xsd.decimal))
[error]                                  ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:367: not found: value TypedLiteral
[error]   val t9 = Triple(timbl,hasCats,TypedLiteral(".5e-42",xsd.double))
[error]                                 ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:368: not found: value TypedLiteral
[error]   val t10 = Triple(presbrey,hasCats,TypedLiteral("3.14",xsd.decimal))
[error]                                     ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:372: not found: value Graph
[error]       val g = Graph(t8,t8bis,t9,t10)
[error]               ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:392: not found: value iriAsN3
[error]       """.format(iriAsN3(hjs))
[error]                  ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:400: not found: type TypedLiteral
[error]   val nums = Map[TypedLiteral,Boolean](
[error]                  ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:439: not found: value BNode
[error]     val t1 = Triple(BNode("_:n22"),foaf.name, "Alexandre" lang "fr" )
[error]                     ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:462: not found: value BNode
[error]     val bn = BNode();
[error]              ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:490: type mismatch;
[error]  found   : org.w3.banana.RDFOperations[Rdf]
[error]  required: String
[error]     val shop = Prefix("http://shop.example/product/", ops)
[error]                                                       ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:528: not found: value BNode
[error]     val bn1 = BNode(); val bn2 = BNode(); val bn3 = BNode(); val bn4 = BNode()
[error]               ^
[error] /Users/Jon/Projects/banana-rdf/n3-test-suite/src/main/scala/TurtleSpec.scala:579: not found: value URI
[error]      val tr = Triple(URI("http://example.org/resource15"),URI("http://example.org/property"),BNode("anon"))
[error]                      ^
[warn] one warning found
[error] 54 errors found
[error] {file:/Users/Jon/Projects/banana-rdf/}banana-n3-test-suite/compile:compile: Compilation failed
[error] Total time: 6 s, completed Jul 10, 2012 10:12:07 AM
> 

SPARQL bindings need more flexible bindings

When one wants to create a binding to a RDF#URI as in

    r.executeSelect(query, Map("webid" -> wid)) 

then Map[String,Node] is not flexible enough, as the above will create a Map[String,RDF#URI] which cannot be passed ( it seems, perhaps I did not verify that carefully enough)

patch is here:
bblfish@8ed6f4e

Sesame. Reuse same repository connection for many of requests.

A lot of times I want to make a bunch of operations and send all of them in a single request. So a lot of code have the same patter:

use(repository.getConnection) { implicit con =>
   con.setAutoCommit(false)
   // some operations 
   con.commit
}

But this approach doesn't fit into banana-rdf RDFStrore/GraphSotre/etc. interface. So is it possible to add this pseudo transactional layer to generic interface? Also does it make any sense for Jena users? I am willing to help with this if someone else is interesting.

do not make use of enhanced syntax

... in the code itself (especially Diesel).

Instead, call the bare functions (like the ones in RDFOperations) and make the calls to the typeclass instances explicit.

ldp: port to banana-0.4

The code in the ldp directory relies on Plantain, which no longer exists. Port it to the abstract banana libs.

PROPOSAL: replace addNamedGraph and appendToNamedGraph with addToNamedGraph

Right now, the graph-store API defines both addNamedGraph and appendToNamedGraph. I think more and more that overriding (as in updating) a graph is an anti-pattern and that users should be encouraged to only add information to a graph (and create it if didn't exist beforehand).

PROPOSAL: replace addNamedGraph and appendToNamedGraph with addToNamedGraph.

Fix build configuration and wrong dependencies

1.Add links to repositories with builds or publish artifacts to central repositories.
2. I am unable to use banana-rdf due to unresolved dependency
"Artifact 'javax.transaction:jta:1.0.1B@jar' not found.". At the same time I see this jar in local repo.
3.Add local maven repo as repository for publishing. I could build banana from source, but can't use in gradle because artifact is located in ivy repo.

new types for relative uris and relative graphs

Perhaps it would be useful to create types for relative URIs and relative graphs.

type URI <: rURI

Then one could have two types of graphs Graph[URI] and Graph[rURI] == rGraph where the type specifies the upper limit for the URI. All else would remain the same.

This would just help make it clearer what could be done with the different graphs. For serialisation an rGraph would be fine. For reasoning only Graphs would be useable. Then there are interesting cases where one may

case class LDPR(uri: URI, graph: rGraph)

or perhaps

case class LDPR(uri: rURI, graph rGraph, container: LDPC)

where the container fills in the rest of the URI?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.