Skip to content

Commit

Permalink
make lastModificationDate mandatory and add UpgradePlugin
Browse files Browse the repository at this point in the history
  • Loading branch information
seakayone committed Nov 29, 2022
1 parent eaae30b commit 1d366f8
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 8 deletions.
4 changes: 2 additions & 2 deletions knora-ontologies/knora-base.ttl
Expand Up @@ -19,7 +19,7 @@
rdf:type owl:Ontology ;
rdfs:label "The Knora base ontology"@en ;
:attachedToProject knora-admin:SystemProject ;
:ontologyVersion "knora-base v25" .
:ontologyVersion "knora-base v26" .


#################################################################
Expand Down Expand Up @@ -1820,7 +1820,7 @@
owl:cardinality "1"^^xsd:nonNegativeInteger ],
[ rdf:type owl:Restriction ;
owl:onProperty :lastModificationDate ;
owl:maxCardinality "1"^^xsd:nonNegativeInteger ],
owl:cardinality "1"^^xsd:nonNegativeInteger ],
[ rdf:type owl:Restriction ;
owl:onProperty :deleteDate ;
owl:maxCardinality "1"^^xsd:nonNegativeInteger ],
Expand Down
2 changes: 1 addition & 1 deletion webapi/src/main/scala/org/knora/webapi/package.scala
Expand Up @@ -11,7 +11,7 @@ package object webapi {
* The version of `knora-base` and of the other built-in ontologies that this version of Knora requires.
* Must be the same as the object of `knora-base:ontologyVersion` in the `knora-base` ontology being used.
*/
val KnoraBaseVersion: String = "knora-base v25"
val KnoraBaseVersion: String = "knora-base v26"

/**
* `IRI` is a synonym for `String`, used to improve code readability.
Expand Down
@@ -1,7 +1,6 @@
package org.knora.webapi.store.triplestore.upgrade

import com.typesafe.scalalogging.Logger

import org.knora.webapi.store.triplestore.upgrade.plugins._

/**
Expand Down Expand Up @@ -53,7 +52,8 @@ object RepositoryUpdatePlan {
PluginForKnoraBaseVersion(versionNumber = 22, plugin = new UpgradePluginPR2081(log)),
PluginForKnoraBaseVersion(versionNumber = 23, plugin = new UpgradePluginPR2094(log)),
PluginForKnoraBaseVersion(versionNumber = 24, plugin = new NoopPlugin), // PR 2076
PluginForKnoraBaseVersion(versionNumber = 25, plugin = new UpgradePluginPR2255(log))
PluginForKnoraBaseVersion(versionNumber = 25, plugin = new UpgradePluginPR2255(log)),
PluginForKnoraBaseVersion(versionNumber = 26, plugin = new UpgradePluginPR2288(log))
// KEEP IT ON THE BOTTOM
// From "versionNumber = 6" don't use prBasedVersionString!
)
Expand Down
@@ -0,0 +1,34 @@
package org.knora.webapi.store.triplestore.upgrade.plugins

import com.typesafe.scalalogging.Logger
import org.knora.webapi.messages.util.rdf.{RdfFeatureFactory, RdfModel, Statement}
import org.knora.webapi.store.triplestore.upgrade.UpgradePlugin

import scala.concurrent.duration.DurationLong

class UpgradePluginPR2288(log: Logger) extends UpgradePlugin {
private val nodeFactory = RdfFeatureFactory.getRdfNodeFactory()

private val creationDateIri = nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-base#creationDate")
private val lastModDateIri = nodeFactory.makeIriNode("http://www.knora.org/ontology/knora-base#lastModificationDate")

override def transform(model: RdfModel): Unit = {
val t0 = System.nanoTime()
log.info(s"Starting ${this.getClass.getSimpleName}")

val statementsWithCreationDateIri =
LazyList.from(model.find(subj = None, pred = Some(creationDateIri), obj = None))

val subjectHasNoLastModificationDate: Statement => Boolean = statement =>
model.find(subj = Some(statement.subj), pred = Some(lastModDateIri), obj = None).isEmpty

val newStatements = statementsWithCreationDateIri
.filter(subjectHasNoLastModificationDate)
.map(s => nodeFactory.makeStatement(s.subj, lastModDateIri, s.obj, s.context))

model.addStatements(newStatements.toSet)

log.info(s"Created ${newStatements.size} new statements:\n${newStatements.mkString("++ ", "\n", "")}")
log.info(s"Finished ${this.getClass.getSimpleName} in " + (System.nanoTime() - t0).nanos.toCoarsest.toString())
}
}
@@ -0,0 +1,56 @@
package org.knora.webapi.store.triplestore.upgrade.plugins

import com.typesafe.scalalogging.LazyLogging
import org.knora.webapi.messages.util.rdf._

class UpgradePluginPR2288Spec extends UpgradePluginSpec with LazyLogging {

val plugin = new UpgradePluginPR2288(log)

val nf = RdfFeatureFactory.getRdfNodeFactory()
val lastModDateIri = nf.makeIriNode("http://www.knora.org/ontology/knora-base#lastModificationDate")
val thingWithoutIri = nf.makeIriNode("http://rdfh.ch/0001/thing-without-mod-date")
val thingWithoutValue =
nf.makeDatatypeLiteral("2020-01-01T10:00:00.673298Z", "http://www.w3.org/2001/XMLSchema#dateTime")
val thingWithIri = nf.makeIriNode("http://rdfh.ch/0001/thing-with-mod-date")
val thingWithValue =
nf.makeDatatypeLiteral("2020-03-01T10:00:00.673298Z", "http://www.w3.org/2001/XMLSchema#dateTime")

val modelStr =
"""
|@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|@prefix knora-base: <http://www.knora.org/ontology/knora-base#> .
|@prefix anything: <http://www.knora.org/ontology/0001/anything#> .
|
|<http://rdfh.ch/0001/thing-without-mod-date>
| a anything:Thing ;
| knora-base:creationDate "2020-01-01T10:00:00.673298Z"^^xsd:dateTime .
|
|<http://rdfh.ch/0001/thing-with-mod-date>
| a anything:Thing ;
| knora-base:creationDate "2020-02-01T10:00:00.673298Z"^^xsd:dateTime ;
| knora-base:lastModificationDate "2020-03-01T10:00:00.673298Z"^^xsd:dateTime .
|
|""".stripMargin

"Upgrade plugin PR2288" should {
"add a statement if creationDate is given but no lastModificationDate" in {
val model: RdfModel = stringToModel(modelStr)
val sizeBefore = model.size

plugin.transform(model)

val expected = nf.makeStatement(thingWithoutIri, lastModDateIri, thingWithoutValue)
assert(model.contains(expected), "Statement is present")
assert(model.size - sizeBefore == 1, "One statement was added ")
}
"not change existing statements if creationDate and lastModificationDate are present" in {
val model: RdfModel = stringToModel(modelStr)

plugin.transform(model)

val expected = nf.makeStatement(thingWithIri, lastModDateIri, thingWithValue)
assert(model.contains(expected))
}
}
}
Expand Up @@ -9,12 +9,12 @@ import com.typesafe.scalalogging.Logger
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike

import java.io.BufferedInputStream
import java.io.FileInputStream

import java.io.{BufferedInputStream, ByteArrayInputStream, FileInputStream}
import org.knora.webapi.messages.util.ErrorHandlingMap
import org.knora.webapi.messages.util.rdf._

import scala.util.Using

/**
* Provides helper methods for specs that test upgrade plugins.
*/
Expand All @@ -37,6 +37,16 @@ abstract class UpgradePluginSpec extends AnyWordSpecLike with Matchers {
rdfModel
}

/**
* Parses a TriG String and returns it as an [[RdfModel]].
*
* @param s the [[String]] content of a "TriG file".
* @return an [[RdfModel]].
*/
def stringToModel(s: String): RdfModel =
Using(new ByteArrayInputStream(s.getBytes))(rdfFormatUtil.inputStreamToRdfModel(_, TriG)).get


/**
* Wraps expected SPARQL SELECT results in a [[SparqlSelectResultBody]].
*
Expand Down

0 comments on commit 1d366f8

Please sign in to comment.