Skip to content

Commit

Permalink
fix!: transform valueHasUri values from node to string type (DEV-1047) (
Browse files Browse the repository at this point in the history
#2094)

* add test data

* add plugin and test

* add plugin to Upgrade plan + increase knora-base version

* cleanup
  • Loading branch information
mpro7 committed Jul 13, 2022
1 parent 9fa26db commit e1d8d95
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -36,7 +36,7 @@ sipi/test
*.bak
*.rdb
.sbtrc
**/*.trig
/*.trig

dependencies.txt
/client-test-data.zip
Expand Down
2 changes: 1 addition & 1 deletion 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 v22" .
:ontologyVersion "knora-base v23" .


#################################################################
Expand Down
12 changes: 12 additions & 0 deletions test_data/upgrade/pr2094.trig
@@ -0,0 +1,12 @@
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix knora-base: <http://www.knora.org/ontology/knora-base#> .

# bad valueHasUri value and missing datatype
<http://rdfh.ch/0103/5LE8P57nROClWUxEPJhiug/values/fEbt5NzaSe6GnCqKoF4Nhg/standoff/2>
rdf:type knora-base:StandoffUriTag ;
knora-base:standoffTagHasEnd 50 ;
knora-base:standoffTagHasStart 20 ;
knora-base:standoffTagHasStartIndex 2 ;
knora-base:standoffTagHasStartParent <http://rdfh.ch/0103/5LE8P57nROClWUxEPJhiug/values/fEbt5NzaSe6GnCqKoF4Nhg/standoff/1> ;
knora-base:standoffTagHasUUID "dd2e785b-041e-4bcb-a77d-570efe8a068c" ;
knora-base:valueHasUri <http://www.maison-george-sand.fr/> .
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 v22"
val KnoraBaseVersion: String = "knora-base v23"

/**
* `IRI` is a synonym for `String`, used to improve code readability.
Expand Down
Expand Up @@ -49,7 +49,8 @@ object RepositoryUpdatePlan {
PluginForKnoraBaseVersion(versionNumber = 14, plugin = new NoopPlugin), // PR 1992
PluginForKnoraBaseVersion(versionNumber = 20, plugin = new UpgradePluginPR2018(log)),
PluginForKnoraBaseVersion(versionNumber = 21, plugin = new UpgradePluginPR2079(log)),
PluginForKnoraBaseVersion(versionNumber = 22, plugin = new UpgradePluginPR2081(log))
PluginForKnoraBaseVersion(versionNumber = 22, plugin = new UpgradePluginPR2081(log)),
PluginForKnoraBaseVersion(versionNumber = 23, plugin = new UpgradePluginPR2094(log))
// KEEP IT ON THE BOTTOM
// From "versionNumber = 6" don't use prBasedVersionString!
)
Expand Down
Expand Up @@ -38,7 +38,7 @@ class UpgradePluginPR2079(log: Logger) extends UpgradePlugin {
)

log.info(
s"Transformed valueHasIri: $literal to ${newObjectValue(literal.value)}."
s"Transformed valueHasUri: $literal to ${newObjectValue(literal.value)}."
)
}

Expand Down
@@ -0,0 +1,52 @@
/*
* Copyright © 2021 - 2022 Swiss National Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.store.triplestore.upgrade.plugins

import com.typesafe.scalalogging.Logger
import org.knora.webapi.messages.OntologyConstants
import org.knora.webapi.messages.util.rdf._
import org.knora.webapi.store.triplestore.upgrade.UpgradePlugin

/**
* Transforms a repository for Knora PR 2094.
* Transforms incorrect value of valueHasUri from node to string type adding also
* missing datatype ^^<http://www.w3.org/2001/XMLSchema#anyURI>
*/
class UpgradePluginPR2094(log: Logger) extends UpgradePlugin {
private val nodeFactory: RdfNodeFactory = RdfFeatureFactory.getRdfNodeFactory()

override def transform(model: RdfModel): Unit = {
val statementsToRemove: collection.mutable.Set[Statement] = collection.mutable.Set.empty
val statementsToAdd: collection.mutable.Set[Statement] = collection.mutable.Set.empty
val newObjectValue: String => DatatypeLiteral = (value: String) =>
nodeFactory.makeDatatypeLiteral(value, OntologyConstants.Xsd.Uri)

for (statement: Statement <- model) {
if (statement.pred.iri == OntologyConstants.KnoraBase.ValueHasUri) {
statement.obj match {
case node: IriNode =>
statementsToRemove += statement

statementsToAdd += nodeFactory.makeStatement(
subj = statement.subj,
pred = statement.pred,
obj = newObjectValue(node.iri),
context = statement.context
)

log.info(
s"Transformed valueHasUri $node to ${newObjectValue(node.iri)}."
)

case _ => ()
}
}
}

model.removeStatements(statementsToRemove.toSet)
model.addStatements(statementsToAdd.toSet)
}
}
@@ -0,0 +1,51 @@
/*
* Copyright © 2021 - 2022 Swiss National Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/

package org.knora.webapi.store.triplestore.upgrade.plugins

import com.typesafe.scalalogging.LazyLogging
import dsp.errors.AssertionException
import org.knora.webapi.messages.OntologyConstants
import org.knora.webapi.messages.util.rdf._

class UpgradePluginPR2094Spec extends UpgradePluginSpec with LazyLogging {
private val nodeFactory: RdfNodeFactory = RdfFeatureFactory.getRdfNodeFactory()

"Upgrade plugin PR2094" should {
"fix the missing valueHasUri datatype" in {
// Parse the input file.
val model: RdfModel = trigFileToModel("../test_data/upgrade/pr2094.trig")

// Use the plugin to transform the input.
val plugin = new UpgradePluginPR2094(log)
plugin.transform(model)

// Check that the datatype was fixed.
val subj =
nodeFactory.makeIriNode("http://rdfh.ch/0103/5LE8P57nROClWUxEPJhiug/values/fEbt5NzaSe6GnCqKoF4Nhg/standoff/2")
val pred = nodeFactory.makeIriNode(OntologyConstants.KnoraBase.ValueHasUri)

model
.find(
subj = Some(subj),
pred = Some(pred),
obj = None
)
.toSet
.headOption match {
case Some(statement: Statement) =>
statement.obj match {
case datatypeLiteral: DatatypeLiteral =>
assert(datatypeLiteral.datatype == OntologyConstants.Xsd.Uri)

case other =>
throw AssertionException(s"Unexpected object for $pred: $other")
}

case None => throw AssertionException(s"No statement found with subject $subj and predicate $pred")
}
}
}
}

0 comments on commit e1d8d95

Please sign in to comment.