Skip to content
Jean-Marc Vanel edited this page Jan 28, 2020 · 6 revisions

Table of Contents

Form generator

Design

There are 2 steps in form generation:

  • abstract form generation
  • HTML generation

The first step generates a FormSyntax case class instance. It depends on the TDB database through the RDFStoreLocalProvider[Rdf, DATASET] trait.

The second step only depends on the FormSyntax case class.

The FormSyntax case class is in close correspondance with the JSON returned by services

  • /form-data
  • /create-data,
  • /sparql-data

(see Services specified by W3C recommandations: SPARQL, LDP )

MVC, you said MVC ?

SF fits within the conceptual frame for Model - View - Controller design pattern.

With the Banana RDF API, there is no need for a Object Semantic Mapping, one works directly with the RDF triples.

API

Basically the API allows to create a form for an instance URI, or for a class URI, or for a form specification URI.

An example using the API is the /login page in AuthServiceTrait.scala. Beyond the typical forms in SF generic application, it has these features:

  • several forms in one HTML page
  • the form is a "pure" form, not used for RDF triples to be stored in the SPARQL database
  • the form action URI is different from the one used for "normal" RDF data forms, /save

RDF (SPARQL) cache

This piece of software allows SF to be a turning table between a number of producers & consumers of RDF.

It is implemented in trait RDFCacheAlgo[Rdf <: RDF, DATASET] .

User management

There are several components:

  • database TDB3/ for user And Password association
  • trait Authentication , a facade for user Authentication management; wraps the TDB database; the signin() function annotates the user graph URI as a foaf:OnlineAccount
  • the /login , /authenticate , /register , /register , /logout pages are in AuthServiceTrait.scala

RDF based HTTP Controller/router

The object SemanticController allows to create new pages or services without relying on routes file of Play! framework,

To create a new service, just implement the interface in trait SemanticController, and add this to val actions in object SemanticController.

Examples:

http://localhost:9000/page?feature=geoloc:stats http://localhost:9000/page?feature=dbpedia:Contact_manager

Callbacks for HTTP events

The trait ServiceListener[Rdf <: RDF, DATASET] is a general callback for HTTP requests, with single abstract function:

def notifyServiceCall(request: HTTPrequest)(implicit userURI: String,
                      rdfLocalProvider: RDFStoreLocalProvider[Rdf, DATASET]): Unit

It is currently implemented by RDFLinksCounterLoadListenerClass, which is instanciated at the beginning of trait ApplicationFacadeImpl[Rdf, DATASET] . The instanciated implementations are called for page /display in trait WebPages by callAllServiceListeners(request) . They could be called for other pages or services as well.

There is another callback, **SaveListener[Rdf]``**, which is also instanciated at the beginning of trait ApplicationFacadeImpl[Rdf, DATASET]. The callbacks are called for service/save` . The implementations are:

  • TimeSeries, which builds the history database in TDB2/ : timestamps for named graphs and user entered triples
  • RDFLinksCounterListenerClass, which builds the database of RDF Links Counts in TDB

Goodies

CSV importer, ...

Update dependencies

Here is a list of dependencies frequently updated. This shows the file (in semantic_forms/scala), and the relevant line:

build.sbt
  scalaVersion in ThisBuild := "2.12.8"
project/build.properties
  sbt.version=1.2.8
project/plugins.sbt
  addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.20")
project/Common.scala
  val jenaVersion =  "3.9.0"