Skip to content

Commit

Permalink
fix!: fix valueHasUri bad values and missing types (DEV-1036) (#2079)
Browse files Browse the repository at this point in the history
* add plugin, test and test data

* add another case to fix

* fix filenames

* add logging & plugin to repo upgrade plan

* cleanup

* review changes

* fix knora-base version

* remove the standoff case
  • Loading branch information
mpro7 committed Jun 21, 2022
1 parent ef3634e commit de1e5a4
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 4 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Expand Up @@ -21,6 +21,7 @@ sipi/test
/docs/architecture/.structurizr
/docs/architecture/workspace.json


**/target/
*.aux
*.bbl
Expand All @@ -35,15 +36,14 @@ sipi/test
*.bak
*.rdb
.sbtrc
.trig
*.trig

dependencies.txt
/client-test-data.zip
/sipi/images/082E/*
/sipi/images/originals/082E/*
sipi/images/1111/*
sipi/images/originals/1111/*
/dependencies.bzl

.idea/
.metals/
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 v20" .
:ontologyVersion "knora-base v21" .


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

# value with missing valueHasUri datatype
<http://rdfh.ch/0103/fN89IUgvSSyMxJ7XWssP9w/values/Rl2rfjDlRBWeuRr-EgIgCw>
rdf:type knora-base:UriValue ;
knora-base:attachedToUser <http://rdfh.ch/users/user-unil-valentina-ponzetto> ;
knora-base:hasPermissions "CR knora-admin:ProjectAdmin|D knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser,knora-admin:UnknownUser" ;
knora-base:isDeleted false ;
knora-base:valueCreationDate "2018-01-12T19:21:37.991+00:00"^^xsd:dateTime ;
knora-base:valueHasOrder 1 ;
knora-base:valueHasString "https://viaf.org/viaf/2571146" ;
knora-base:valueHasUUID "PYQ5mqH8TYOKCytMozecWw" ;
knora-base:valueHasUri "https://viaf.org/viaf/2571146" .
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 v20"
val KnoraBaseVersion: String = "knora-base v21"

/**
* `IRI` is a synonym for `String`, used to improve code readability.
Expand Down
Expand Up @@ -54,6 +54,11 @@ object RepositoryUpdatePlan {
versionNumber = 20,
plugin = new UpgradePluginPR2018(featureFactoryConfig, log),
prBasedVersionString = Some("PR 2018")
),
PluginForKnoraBaseVersion(
versionNumber = 21,
plugin = new UpgradePluginPR2079(featureFactoryConfig, log),
prBasedVersionString = Some("PR 2079")
)
)

Expand Down
@@ -0,0 +1,54 @@
/*
* 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.feature.FeatureFactoryConfig
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 2079.
* Adds missing datatype ^^<http://www.w3.org/2001/XMLSchema#anyURI> and/or value to valueHasUri
*/
class UpgradePluginPR2079(featureFactoryConfig: FeatureFactoryConfig, log: Logger) extends UpgradePlugin {
private val nodeFactory: RdfNodeFactory = RdfFeatureFactory.getRdfNodeFactory(featureFactoryConfig)

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 literal: DatatypeLiteral =>
if (literal.datatype != OntologyConstants.Xsd.Uri) {
statementsToRemove += statement

statementsToAdd += nodeFactory.makeStatement(
subj = statement.subj,
pred = statement.pred,
obj = newObjectValue(literal.value),
context = statement.context
)

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

case _ => ()
}
}
}

model.removeStatements(statementsToRemove.toSet)
model.addStatements(statementsToAdd.toSet)
}
}
@@ -0,0 +1,50 @@
/*
* 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 UpgradePluginPR2079Spec extends UpgradePluginSpec with LazyLogging {
private val nodeFactory: RdfNodeFactory = RdfFeatureFactory.getRdfNodeFactory(defaultFeatureFactoryConfig)

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

// Use the plugin to transform the input.
val plugin = new UpgradePluginPR2079(defaultFeatureFactoryConfig, log)
plugin.transform(model)

// Check that the datatype was fixed.
val subj = nodeFactory.makeIriNode("http://rdfh.ch/0103/fN89IUgvSSyMxJ7XWssP9w/values/Rl2rfjDlRBWeuRr-EgIgCw")
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 de1e5a4

Please sign in to comment.